By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,997 Members | 1,270 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,997 IT Pros & Developers. It's quick & easy.

Help With Strings

P: n/a
Hello friends at comp.lang.c,

I'm trying to combine 2 strings with a newline character at the end to write
to a file. When I view the file, the messages run together and some of the
str string is cut-off. A portion of the code is below. Any help would be
appreciated.

#define MAX_SIZE 256
char str[MAX_SIZE];
char lev[] = "INFO: ";
va_list ap;

va_start(ap, fmt);
vsprintf(str, fmt, ap);
va_end(ap);

strcat(lev, str);

write(fd, lev, strlen(fmt));
Nov 14 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
"Craig" <NO****************@highstream.net> writes:
I'm trying to combine 2 strings with a newline character at the end to write
to a file. When I view the file, the messages run together and some of the
str string is cut-off. A portion of the code is below. Any help would be
appreciated.

#define MAX_SIZE 256
char str[MAX_SIZE];
char lev[] = "INFO: ";
va_list ap;

va_start(ap, fmt);
vsprintf(str, fmt, ap);
va_end(ap);

strcat(lev, str);

write(fd, lev, strlen(fmt));


The variable lev has a size of 7 bytes (6 for the characters of the
string literal used to initialize it, plus 1 for the trailing '\0').
You use strcat() to append more characters, but here's no room for
them. The result is undefined behavior, most likely overwriting some
other chunk of memory.

(You also risk writing past the end of str with your vsprintf() call,
unless you're positive that MAX_SIZE is big enough.)

Also, standard C has no write() function; fwrite() is standard and
more portable. That's not relevant to your problem, but it's
something you should be aware of.

I'm now going to go off on a tangent.

Speaking of that, I'm curious about something. ISO C defines the
fread() and fwrite() functions, and all the other stuff in <stdio.h>
that operates on FILE*'s. POSIX defines read() and write(), and all
the other stuff that operates on file descriptors (small integers).
Historically, I think that read() and write() are probably as old as,
or older than, fread() and fwrite(); ANSI chose to standardize the
latter, but not the former. Are there any real-world hosted
implementations that support fread() and fwrite() but *don't* also
support read() and write(), or is the historical precedent strong
enough to make read() and write() effectively universal?

I'm not at all suggesting that read()/write() should be part of
standard C, or that they should be considered topical here. I'm just
curious about their status.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #2

P: n/a
Keith Thompson wrote:
[...]
I'm now going to go off on a tangent.

Speaking of that, I'm curious about something. ISO C defines the
fread() and fwrite() functions, and all the other stuff in <stdio.h>
that operates on FILE*'s. POSIX defines read() and write(), and all
the other stuff that operates on file descriptors (small integers).
Historically, I think that read() and write() are probably as old as,
or older than, fread() and fwrite(); ANSI chose to standardize the
latter, but not the former. Are there any real-world hosted
implementations that support fread() and fwrite() but *don't* also
support read() and write(), or is the historical precedent strong
enough to make read() and write() effectively universal?


The Rationale discusses the C89 committee's thoughts on
the matter. The crux, it appears, is that read() et al. treat
a file as an array of characters, but this treatment is not
appropriate for all systems -- particularly for text files.
On a system where text lines are terminated with a CR/LF pair,
for example, what would be the semantics of lseek()ing to a
point just after the CR and then reading? Is the end-of-line
sequence recognizable in medias res?

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 14 '05 #3

P: n/a


Craig wrote:
Hello friends at comp.lang.c,

I'm trying to combine 2 strings with a newline character at the end to write
to a file. When I view the file, the messages run together and some of the
str string is cut-off. A portion of the code is below. Any help would be
appreciated.

#define MAX_SIZE 256
char str[MAX_SIZE];
char lev[] = "INFO: ";
va_list ap;

va_start(ap, fmt);
vsprintf(str, fmt, ap);
va_end(ap);

strcat(lev, str);


Since lev is an array of 7 characters, appending to it
is flawed. Make lev a large enough array to hold all the characters.
char lev[LARGE_ENOUGH] = "INFO: ";

If you are only concerned with the final goal of getting the strings
to a file, there is no need to combine in a character array and then
copy to a file. Just copy one string to the file, then append to the
file the other string followed by appending the newline character.
This can all be done with one statement using function fprintf.

fprintf(fp,"%s%s\n",string1,string2);

Example:

#include <stdio.h>

#define FNAME "test1.txt"

int main(void)
{
char *s1 = "INFO: ";
char *s2 = "We are go for launch.";
int ch;
FILE *fp;

if((fp = fopen(FNAME,"w+")) != NULL)
{
fprintf(fp,"%s%s\n",s1,s2);
/* to test it */
rewind(fp);
puts("\tReading from the file, the line is:");
for( ; (ch = fgetc(fp)) != EOF; ) putchar(ch);
fclose(fp);
remove(FNAME);
}
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #4

P: n/a
Eric Sosman <es*****@acm-dot-org.invalid> writes:
Keith Thompson wrote:
[...]
I'm now going to go off on a tangent.
Speaking of that, I'm curious about something. ISO C defines the
fread() and fwrite() functions, and all the other stuff in <stdio.h>
that operates on FILE*'s. POSIX defines read() and write(), and all
the other stuff that operates on file descriptors (small integers).
Historically, I think that read() and write() are probably as old as,
or older than, fread() and fwrite(); ANSI chose to standardize the
latter, but not the former. Are there any real-world hosted
implementations that support fread() and fwrite() but *don't* also
support read() and write(), or is the historical precedent strong
enough to make read() and write() effectively universal?


The Rationale discusses the C89 committee's thoughts on
the matter. The crux, it appears, is that read() et al. treat
a file as an array of characters, but this treatment is not
appropriate for all systems -- particularly for text files.
On a system where text lines are terminated with a CR/LF pair,
for example, what would be the semantics of lseek()ing to a
point just after the CR and then reading? Is the end-of-line
sequence recognizable in medias res?


The standard fread()/fwrite() system very nearly treats files as
arrays of characters except for the behavior on end-of-line (and
that's only for text mode). lseek() on a text file with CR/LF pairs
presumably behaves similarly to fseek() on the same file opened in
binary mode.

But my question wasn't about the rationale for the choices made in
standardizing one interface but not the other. (Personally I think it
was a good choice; imposing that kind of redundancy on all
implementations doesn't seem like a good idea.) The question was
whether any real-world implementations actually provide
fread()/fwrite() without providing read()/write(). I ask out of idle
curiosity, not out of any intent to use the knowledge for evil.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #5

P: n/a
Keith Thompson wrote:

But my question wasn't about the rationale for the choices made in
standardizing one interface but not the other. (Personally I think it
was a good choice; imposing that kind of redundancy on all
implementations doesn't seem like a good idea.) The question was
whether any real-world implementations actually provide
fread()/fwrite() without providing read()/write(). I ask out of idle
curiosity, not out of any intent to use the knowledge for evil.


System vendors have an incentive to support as many
relevant Standards as possible with reasonable effort.
Most systems (for suitable values of "most") make an effort
to support both the C Standard and at least some of the
POSIX Standards, so read() et al. will be available on
about as many (for suitable values of "as many") systems
as fread() and friends.

That said, there certainly exist systems where neither
fread() nor read() is "native." (Open)VMS is one such, or
at least it was so when I last used it not quite a decade
ago. On VMS, fread() was not layered atop read(); both were
emulated semi-independently atop VMS' own file model. (As
it happens, neither C streams nor POSIX files are adequate
models for the semantics of all VMS file types.)

--
Eric Sosman
es*****@acm.org
Nov 14 '05 #6

P: n/a
"Al Bowers" <xa******@rapidsys.com> wrote in message
news:38*************@individual.net...


Craig wrote:
Hello friends at comp.lang.c,

I'm trying to combine 2 strings with a newline character at the end to write to a file. When I view the file, the messages run together and some of the str string is cut-off. A portion of the code is below. Any help would be appreciated.

#define MAX_SIZE 256
char str[MAX_SIZE];
char lev[] = "INFO: ";
va_list ap;

va_start(ap, fmt);
vsprintf(str, fmt, ap);
va_end(ap);

strcat(lev, str);


Since lev is an array of 7 characters, appending to it
is flawed. Make lev a large enough array to hold all the characters.
char lev[LARGE_ENOUGH] = "INFO: ";

If you are only concerned with the final goal of getting the strings
to a file, there is no need to combine in a character array and then
copy to a file. Just copy one string to the file, then append to the
file the other string followed by appending the newline character.
This can all be done with one statement using function fprintf.

fprintf(fp,"%s%s\n",string1,string2);

Example:

#include <stdio.h>

#define FNAME "test1.txt"

int main(void)
{
char *s1 = "INFO: ";
char *s2 = "We are go for launch.";
int ch;
FILE *fp;

if((fp = fopen(FNAME,"w+")) != NULL)
{
fprintf(fp,"%s%s\n",s1,s2);
/* to test it */
rewind(fp);
puts("\tReading from the file, the line is:");
for( ; (ch = fgetc(fp)) != EOF; ) putchar(ch);
fclose(fp);
remove(FNAME);
}
return 0;
}
--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/


Thanks for the replies. I should posted my message sooner. I tried
increasing the buffer size but it didn't correct the problem so I decided to
re-write the function using fopen and fprintf. The message is written to
the file properly now except for when it is called by a test program that is
supposed to write 1000 messages. The function only writes messages 0
through 252. Any ideas why all the messages aren't being written and what
to do about it?
Nov 14 '05 #7

P: n/a
In article <11*************@corp.supernews.com>,
Craig <NO****************@highstream.net> wrote:
:I tried
:increasing the buffer size but it didn't correct the problem so I decided to
:re-write the function using fopen and fprintf. The message is written to
:the file properly now except for when it is called by a test program that is
:supposed to write 1000 messages. The function only writes messages 0
:through 252. Any ideas why all the messages aren't being written and what
:to do about it?

Are you using fopen() once per message? If so then my guess would be that
you are not fclose()'ing each after you are done. If you keep opening
files without closing them, you are going to run into an implimentation-
dependant maximum number of files that may be simultaneously open.

It is not uncommon for the limit on the number of open files to be
the one implied by the internal use of a char to store the underlying
descriptor number. On systems with 8 bit characters, that allows at
most 256 open files. 3 descriptors are certain to be in use when
the program starts: standard input, standard output, and standard error.
You observe 252; add 3 and you are at 255. The missing last descriptor
is experimental error ;-)
--
This is not the same .sig the second time you read it.
Nov 14 '05 #8

P: n/a


Craig wrote:
Craig wrote:
Hello friends at comp.lang.c,

I'm trying to combine 2 strings with a newline character at the end to
write
to a file. When I view the file, the messages run together and some of
the
str string is cut-off.

Thanks for the replies. I should posted my message sooner. I tried
increasing the buffer size but it didn't correct the problem so I decided to
re-write the function using fopen and fprintf. The message is written to
the file properly now except for when it is called by a test program that is
supposed to write 1000 messages. The function only writes messages 0
through 252. Any ideas why all the messages aren't being written and what
to do about it?

You need to provide the code, at least for the function you mention.

In general, I think you will want to:
1. Open the file for writing.
2. write the 1000 lines to the file with fprintf, or the function
you mentioned.. Check the return value of fprintf in order to
catch a file write error.
3. close the file.

Example:

#include <stdio.h>

#define FNAME "test1.txt"

int WriteData(FILE *fp,const char *s1, const char *s2)
{
return fprintf(fp,"%s%s\n",s1,s2);
}

int main(void)
{
char *s1 = "Test Message Line", info[32];
int ch,i;
FILE *fp;

if((fp = fopen(FNAME,"w+")) != NULL)
{
for(i = 0; i < 1000; i++)
{
sprintf(info,"%s %d",s1,i+1);
if(0 > WriteData(fp,"INFO: ", info)) break;
}
/* to test it */
rewind(fp);
if(i != 1000) puts("Oops! A File Write Error");
else
{
for( ; (ch = fgetc(fp)) != EOF; ) putchar(ch);
puts("END OF FILE");
}
fclose(fp);
remove(FNAME);
}
else puts("Unable to open file for update");
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #9

P: n/a
"Al Bowers" <xa******@rapidsys.com> wrote in message
news:38*************@individual.net...


Craig wrote:
Craig wrote:

Hello friends at comp.lang.c,

I'm trying to combine 2 strings with a newline character at the end to


write
to a file. When I view the file, the messages run together and some of


the
str string is cut-off.

Thanks for the replies. I should posted my message sooner. I tried
increasing the buffer size but it didn't correct the problem so I decided to re-write the function using fopen and fprintf. The message is written to the file properly now except for when it is called by a test program that is supposed to write 1000 messages. The function only writes messages 0
through 252. Any ideas why all the messages aren't being written and what to do about it?

You need to provide the code, at least for the function you mention.

In general, I think you will want to:
1. Open the file for writing.
2. write the 1000 lines to the file with fprintf, or the function
you mentioned.. Check the return value of fprintf in order to
catch a file write error.
3. close the file.

Example:

#include <stdio.h>

#define FNAME "test1.txt"

int WriteData(FILE *fp,const char *s1, const char *s2)
{
return fprintf(fp,"%s%s\n",s1,s2);
}

int main(void)
{
char *s1 = "Test Message Line", info[32];
int ch,i;
FILE *fp;

if((fp = fopen(FNAME,"w+")) != NULL)
{
for(i = 0; i < 1000; i++)
{
sprintf(info,"%s %d",s1,i+1);
if(0 > WriteData(fp,"INFO: ", info)) break;
}
/* to test it */
rewind(fp);
if(i != 1000) puts("Oops! A File Write Error");
else
{
for( ; (ch = fgetc(fp)) != EOF; ) putchar(ch);
puts("END OF FILE");
}
fclose(fp);
remove(FNAME);
}
else puts("Unable to open file for update");
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/


Thanks, I just needed the fclose(fp); in the function.
Nov 14 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.