424,279 Members | 1,907 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,279 IT Pros & Developers. It's quick & easy.

How to read a part of a string

P: n/a


if I wanna copy a part of the string to another string.
It is my code, Is it OK? but I have a core dump.
include<stdio.h>
int main()
{
FILE *fp;
fp = fopen("test.txt","r");
char s1[20],s2[5],s3[2];
fscanf(fp,"%s",s1);
printf("s1 is %s\n",s1);
int i;
for(i=0;i<6;i++)
{
s2[i] = s1[1+i];
}
s2[6]='\0';
printf("s2 is %s\n",s2);
s3[0]=s1[10];
s3[1]=s1[11];
s3[2]='\0';
printf("s3 is %s\n",s3);
fclose(fp);
}

Nov 14 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
po***********@gmail.com wrote:

if I wanna copy a part of the string to another string.
It is my code, Is it OK? but I have a core dump.
include<stdio.h>
int main()
{
FILE *fp;
fp = fopen("test.txt","r");
char s1[20],s2[5],s3[2]; fscanf(fp,"%19s",s1); /* Correct me if I'm wrong, but this
should limit
the fscanf call to 19 chars */
s1[19] = 0; /* Ensure that the string is null-terminated */ printf("s1 is %s\n",s1);
int i; for(i=0;i<4;i++) { s2[i] = s1[i]; } s2[4] = 0; /* s2[6] does not exist */ printf("s2 is %s\n",s2);
s3[0]=s1[10]; s3[1]= 0; /* 1 is the last char, and s3[2] does not exist */ printf("s3 is %s\n",s3);
fclose(fp);
}


Your code is overly complicated and hard to understand.
Try something like:

void my_strdup(char[] source, char[] dest, int offset, int length)
{
/* Copy <length> chars from source, starting at <offset>
* It is assumed that dest has enough space for length chars */

for(int i=0; i<length && source[offset+i]; i++)
{
dest[i] = source[offset+i];
}
}

Additionally, see my edits to your code, you appear to have alot of
trouble with C-style arrays and null-terminated strings.
A core-dump is almost always a memory access violation (afaik - I don't
usually do C code)
Nov 14 '05 #2

P: n/a
po***********@gmail.com wrote:

if I wanna copy a part of the string to another string.
It is my code, Is it OK? but I have a core dump.
include<stdio.h>
I hope that was

#include <stdio.h>
int main()
Make that

int main( void )
{
FILE *fp;
fp = fopen("test.txt","r");
char s1[20],s2[5],s3[2];
Do you have a C99 compiler? Otherwise you can't define new variables
after the first executable statement.
fscanf(fp,"%s",s1);
What happens if the string you just read had more than 19 characters?
You better make that

fscanf( fp, "%19s", s1 );

And, of course, you should check the return value of fopen() before
you use 'fp'. Checking the one of fscanf() also won't hurt.
printf("s1 is %s\n",s1);
int i;
for(i=0;i<6;i++)
{
s2[i] = s1[1+i];
}
s2[6]='\0';
You defined 's2' to be an array of 5 chars, but here you're already
using the 7th element that doesn't exist. That won't do. Moreover,
you don't know how many elements of 's1' are set at all - using un-
itialized values is also nothing you try.
printf("s2 is %s\n",s2);
s3[0]=s1[10];
s3[1]=s1[11];
s3[2]='\0';
And here you do it again. 's3' has two elements but you try to use
three.
printf("s3 is %s\n",s3);
fclose(fp);
}


You promised that main() would return an int, but you forgot about
that.
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #3

P: n/a
Arafangion <Ar********@invalid.email.address.com> wrote:
po***********@gmail.com wrote:

if I wanna copy a part of the string to another string.
It is my code, Is it OK? but I have a core dump.
include<stdio.h>
int main()
{
FILE *fp;
fp = fopen("test.txt","r");
char s1[20],s2[5],s3[2]; fscanf(fp,"%19s",s1); /* Correct me if I'm wrong, but this
should limit
the fscanf call to 19 chars */


that's fine. I would also suggest testing if there was a conversion at
all, that is check the return value of fscanf(). Further improvement to
the field width would be using some macros to calculate the maximum
field width automagically.
s1[19] = 0; /* Ensure that the string is null-terminated */


No need for this. the scanf-family ensures this allready.

--
Z (zo**********@web.de)
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
Nov 14 '05 #4

P: n/a
po***********@gmail.com wrote:
if I wanna copy a part of the string to another string.
It is my code, Is it OK? but I have a core dump.
include<stdio.h>
int main()
{
FILE *fp;
fp = fopen("test.txt","r");
char s1[20],s2[5],s3[2];
fscanf(fp,"%s",s1); Running gdb on the program showed that the above line caused
segmentation fault when I did not have "test.txt" in my directory. It
would help as said above to check for return value of fopen and fscanf.
printf("s1 is %s\n",s1);
int i;
for(i=0;i<6;i++)
{
s2[i] = s1[1+i];
}
s2[6]='\0';
printf("s2 is %s\n",s2);
s3[0]=s1[10];
s3[1]=s1[11];
s3[2]='\0';
printf("s3 is %s\n",s3);
fclose(fp);
}

Just ran this program and it does not do what you intended to do. Seems
pretty complex logic.

Nov 14 '05 #5

P: n/a


po***********@gmail.com wrote:
if I wanna copy a part of the string to another string.
It is my code, Is it OK? but I have a core dump.
include<stdio.h>
int main()
{
FILE *fp;
fp = fopen("test.txt","r");
char s1[20],s2[5],s3[2];
fscanf(fp,"%s",s1); Is s1 big enough? printf("s1 is %s\n",s1);
int i;
for(i=0;i<6;i++)
{
s2[i] = s1[1+i];
}
s2[6]='\0'; Declaration s2[5];
there are
s2[0]
s2[1]
s2[2]
s2[3]
s2[4]
5 elements (only) there is no s2[5] or s2[6];
NOTE: If we do research, we would find that
s2[5] = s1[0] and s2[6] = s2[1];
(gcc on x86)
printf("s2 is %s\n",s2);
s3[0]=s1[10];
s3[1]=s1[11];
s3[2]='\0';
There is no s3[2] neither.
printf("s3 is %s\n",s3);
fclose(fp);
}


Why don't you do something like this.

snprintf(s2, 2, "%s", &s1[yourindex]);

instead of using assign char by char

Regards,

Nov 14 '05 #6

P: n/a
On Tue, 07 Jun 2005 00:37:42 -0700, Prawit Chaivong wrote:

....
Declaration s2[5];
there are
s2[0]
s2[1]
s2[2]
s2[3]
s2[4]
5 elements (only) there is no s2[5] or s2[6];
NOTE: If we do research, we would find that
s2[5] = s1[0] and s2[6] = s2[1];
C makes no guarantees about the layout of different objects in memory,
it is pretty much always an error to make use of such information so is
probably a bad idea to even mention it.
(gcc on x86)


Even there it could depend on things like gcc version, optimisation level
etc.
printf("s2 is %s\n",s2);
s3[0]=s1[10];
s3[1]=s1[11];
s3[2]='\0';


There is no s3[2] neither.
printf("s3 is %s\n",s3);
fclose(fp);
}


Why don't you do something like this.

snprintf(s2, 2, "%s", &s1[yourindex]);

instead of using assign char by char


Or possibly

sprintf(s2, "%.2s", &s1[yourindex]);

snprintf and sprintf are fairly heavyweight for this, strncat may be
better:

s2[0] = '\0';
strncat(s2, &s1[yourindex], 2);

Unfortunately strncpy() doesn't do what you might expect and isn't as good
for this.

Lawrence

Nov 14 '05 #7

P: n/a


Lawrence Kirby wrote:
On Tue, 07 Jun 2005 00:37:42 -0700, Prawit Chaivong wrote:

...
Declaration s2[5];
there are
s2[0]
s2[1]
s2[2]
s2[3]
s2[4]
5 elements (only) there is no s2[5] or s2[6];
NOTE: If we do research, we would find that
s2[5] = s1[0] and s2[6] = s2[1];
C makes no guarantees about the layout of different objects in memory,
it is pretty much always an error to make use of such information so is
probably a bad idea to even mention it.
(gcc on x86)


Even there it could depend on things like gcc version, optimisation level
etc.

That's a little addition information from my research.
Do not have to use it.

It's always a good idea to know how does your compiler work.
printf("s2 is %s\n",s2);
s3[0]=s1[10];
s3[1]=s1[11];
s3[2]='\0';
There is no s3[2] neither.
printf("s3 is %s\n",s3);
fclose(fp);
}


Why don't you do something like this.

snprintf(s2, 2, "%s", &s1[yourindex]);

instead of using assign char by char


Or possibly

sprintf(s2, "%.2s", &s1[yourindex]);

snprintf and sprintf are fairly heavyweight for this, strncat may be
better:

Can you explain further why they are heavyweight?
Or recommend me some paper.
s2[0] = '\0';
strncat(s2, &s1[yourindex], 2);

Unfortunately strncpy() doesn't do what you might expect and isn't as good
for this.

Lawrence


Nov 14 '05 #8

P: n/a
On Tue, 07 Jun 2005 03:00:54 -0700, Prawit Chaivong wrote:

....
Even there it could depend on things like gcc version, optimisation level
etc. That's a little addition information from my research.
Do not have to use it.


More specifically in the vast majority of situations you SHOULD NOT use
it.
It's always a good idea to know how does your compiler work.


Not always. Knowledge of how your compiler works can lead to false
assumptions and non-portable code. It isn't appropriate to present such
information in a context like this which is about basic correctness for C
code. Code that goes off the end of an array is simply wrong, irrespective
of what happens to be in memory before and after it. Irrelevant details
like that are simply a recipe for confusion.

Lawrence
Nov 14 '05 #9

P: n/a
In article <11*********************@g47g2000cwa.googlegroups. com>,
po***********@gmail.com wrote:
if I wanna copy a part of the string to another string.
It is my code, Is it OK? but I have a core dump.
include<stdio.h>
int main()
{
FILE *fp;
fp = fopen("test.txt","r");
<delurk> In addition to the other replies, it should be noted that
fopen returns a valid file pointer only if test.txt exists, and was
opened for reading, otherwise fp is set to NULL, so here you need to
test fp for NULL, e.g.
if (fp == NULL)
{
/* take appropriate action */
}
</delurk>
char s1[20],s2[5],s3[2];
fscanf(fp,"%s",s1);
printf("s1 is %s\n",s1);
int i;
for(i=0;i<6;i++)
{
s2[i] = s1[1+i];
}
s2[6]='\0';
printf("s2 is %s\n",s2);
s3[0]=s1[10];
s3[1]=s1[11];
s3[2]='\0';
printf("s3 is %s\n",s3);
fclose(fp);
}

Nov 14 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.