简体   繁体   中英

Create function which copy all values from one char array to another char array in C (segmentation fault)

I have a task. I must copy all values form one char array (sentence[]) to another empty char array sentence2[]), but I don't know why I get segmentation fault. They told us also that we must create own strlen function to check how long is string.

This is my code

#include <stdio.h>
#include <stdlib.h>

int new_strlen (char *tab)
{
    int i;
    for (i = 0; tab[i] != '\0'; ++i);    
    return i;
}

int copyText(char from[],char to[],int max)
{
    int i, j;
    if (new_strlen(from) <= max)
    {
        for(int i = 0; i != '\0'; i++) {
            to[i] = from[i];
        }
        to[i+1] = '\0'; 
    }
    return 0;
}


int main (int argc, char *argv[])
{
    char sentence[] = "C is \n a \n programming \t language";
    char sentence2[1000];

    copyText(sentence, sentence2, 1000);
    printf("Show my array: %s \n", sentence2);

    return 0;
}

Here are the bugs:

int copyText(char from[],char to[],int max)
{
    int i, j;  // minor problem: j is useless

    if (new_strlen(from) <= max)  //  should be < instead of <=
    {
        for(int i = 0; i != '\0'; i++) {  // here you declare a new i variable
                                          // unrelated to the i declared at the beginning
            to[i] = from[i];
        }

        to[i+1] = '\0';        // here you use again the i declared at the beginning
                               // which hasn't been initialized
                               // and i already is the index of the terminator
                               // therefore it should be to[i]
    }

    return 0;
}

This line contains two errors:

for(int i = 0; i != '\0'; i++)
  1. i != '\0' is equivalent to i != 0 . Now youv'e probably realized your error. Actually you need to test if from[i] is 0.

  2. to[i+1] = '\0' : here i has already been incremented by the for loop, i already contains the index of the \0 terminator, therefore it should be to[i] = '\0'

  3. And finally in this line you use the i variable declard at the beginning o the function whose content is indeterminate as you have never assigned anything to it and it is most likely this line that causes the segmentation fault: to[i+1] = '\0' ;

Finally there is another problem that will cause problems if the length of the string is max:

if (new_strlen(from) <= max)  //  should be < instead of <=

If the length of the string is max, then \0 will be put one beyond the end of the buffer, hence a buffer overflow.

You want this:

int copyText(char from[],char to[],int max)
{
    if (new_strlen(from) < max)
    {
        int i;
        for(i = 0; from[i] != '\0'; i++)
            to[i] = from[i];
        }

        to[i] = '\0';
    }

    return 0;
}

Three issues with copyText

  1. i != '\0' should be from[i] != '\0'

  2. int i = 0 should be just i = 0 in for loop to not shadow the other i and also pointless to do it.

  3. to[i+1] should be just to[i]

I modify my program like you said. My program

#include <stdio.h>
#include <stdlib.h>

int new_strlen (char *tab)
{
    int i;
    for (i = 0; tab[i] != '\0'; ++i);    
    return i;
}

int copyText(char from[],char to[],int max)
{
    if (new_strlen(from) < max)
    {
        int i;
        for(int i = 0; from[i] != '\0'; i++)
        {
            to[i] = from[i];
        }

        to[i] = '\0';
    }

    return 0;
}

int main (int argc, char *argv[])
{
    char sentence[] = "C is \n a \n programming \t language";
    char sentence2[30];

    copyText(sentence, sentence2, 30);
    printf("Show my array: %s \n", sentence2);

    return 0;
}

The output

Show my array: h�ܙ� 

Why my output is wrong?

I sloved your problem. You just missed 'form[i]' in for loop of copytext() funtion. And used (new_strlen(from) <= max) instead (new_strlen(from) < max). And removed to[i+1] = '\0'; which was not needed.

#include <stdio.h>
#include <stdlib.h>

int new_strlen (char *tab)
{
    int i;
    for (i = 0; tab[i] != '\0'; ++i);
    return i;
}
int copyText(char from[],char to[],int max)
{
    if (new_strlen(from) <= max)
    {
        for(int i = 0; from[i] != '\0'; i++)
        {
            to[i] = from[i];
        }
    }
    return 0;
}
int main (int argc, char *argv[])
{
    char sentence[] = "C is \n a \n programming \t language";
    char sentence2[1000];
    copyText(sentence, sentence2, 1000);
    printf("Show my array: %s \n", sentence2);
    return 0;
}

I have a task. I must copy all values form one char array (sentence[]) to another empty char array sentence2[]),

I you must copy all values then the third parameter of the function copyText

int copyText(char from[],char to[],int max);

is redundant. In general it does allow to copy all values .

I think that by " all values " you mean all characters of a string stored in the source array.

To copy a string from one character array to another character array the function that calculates the length of the string is not required. It is also redundant.

The return type int of the function copyText does not make a sense. The character array from which the stored string is copied shall have the qualifier const .

Standard C string functions follow the convention that the destination character array should be the first function parameter and functions should return pointer to the destination character array.

Within the function the declared variable j is not used

int i, j;

The reason of the segmentation fault is that you are using the non-initialized variable i to set the terminating zero character in the destination array. That is you declared an uninitialized variable i

int i, j;

then in the if statement in its inner loop

if (new_strlen(from) <= max)
{
    for(int i = 0; i != '\0'; i++) {
        ^^^^^^^^^
        to[i] = from[i];
    }
    to[i+1] = '\0'; 
}

you declared one more variable i which will not be alive outside the loop. The loop itself iterates never because the condition of the loop

i != '\0'

is not satisfied. The variable i was initialized by 0 and is compared with the same 0 that is written as an octal character literal.

So in this statement

    to[i+1] = '\0'; 

there is used the initialized variable i declared in the beginning of the function before the if statement.

I am sure what you are required to write is an analog of ths atndard C function strcpy.

In this case the program can look the following way

#include <stdio.h>

char * copyText( char to[], const char from[] )
{
    for ( char *p = to; ( *p++ = *from++ ) != 0; ) { /* empty */ }

    return to;
}


int main (void)
{
    enum { N = 1000 };
    char sentence[] = "C is \n a \n programming \t language";
    char sentence2[N];

    printf("Show my array: %s \n", copyText(sentence2, sentence ) );

    return 0;
}

The program output is

Show my array: C is 
 a 
 programming     language 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM