How to read a part of a string

P

poison.summer

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 = 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);
}
 
A

Arafangion

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 = s1;
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 = 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)
 
J

Jens.Toerring

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 said:
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 = 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
 
Z

Zoran Cutura

Arafangion said:
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.
 
J

Jaspreet

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 = 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.
 
P

Prawit Chaivong

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 = 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,
 
L

Lawrence Kirby

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
 
P

Prawit Chaivong

Lawrence said:
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
 
L

Lawrence Kirby

On Tue, 07 Jun 2005 03:00:54 -0700, Prawit Chaivong wrote:

....
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
 
D

D Power

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 */
}
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 = 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);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top