assigning a value within a char array pointer

2019-08-16 09:25发布

问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX40 40

/* run this program using the console pauser or add your own getch, system("pause") or input loop */


Int40 *parseString(char *str)
{
    Int40 *p;
    char *ptr;
    int i, len, value, ptrValue;

    printf("%s\n", str);


        for(i = 0; i < 40; i++)
{
    if(str[i] == 'a')
    {
        printf("%c\n", str[i]);
            str[i] = '0';
        printf("%c\n", str[i]);
    }

    }
}

int main(int argc, char *argv[])
 {
 // char string[40] = "
 // char *str = string;
    Int40 *p;


    parseString("0123456789abcdef0123456789abcdef01234567");

    return 0;
}

In my parseString function, between the two printf statements, I'm trying to assign the value at the specific point of 'a' to 0. I'm not sure how I'm supposed to be attempting this, and I would like to keep the variables the same as well.

回答1:

Your problem here is that you are passing to parseString a pointer to a string literal. Modifying the contents of string literals is undefined behaviour and most of the times string literals reside in read only memory, that's why your program crashes.

You have to create an array and initialize it with the string you want, then pass that array to the function:

#include <string.h>

void parseString(char *str, size_t len)
{
    printf("%s\n", str);


    for(size_t i = 0; i < len; i++)
    {
        if(str[i] == 'a')
        {
            printf("%c\n", str[i]);
                str[i] = '0';
            printf("%c\n", str[i]);
        }
    }
}

int main(int argc, char *argv[])
{
    char text[] = "0123456789abcdef0123456789abcdef01234567";

    parseString(text, sizeof text / sizeof *text);

    return 0;
}

Bear in mind when you pass an array to a function, the function gets only a pointer to the first element of the array. For that reason the function being called cannot determine the length of the array. It's better practice to pass the length of the array as well. That's why I added size_t len as an argument in parseString. In main where the array is declared, I calculate the length of the array with sizeof text / size *text. Note that this only works with pure array, if you did sizeof str / sizeof *str in parseString, you will definitively get a wrong result, that's why you should always pass the length of the array.



回答2:

Your program is having undefined behavior.

As per the standard attempting to modify a string literal results in undefined behavior because they may be stored in read-only storage or combined with other string literals.

You are passing string literal to parseString() function:

parseString("0123456789abcdef0123456789abcdef01234567");

and in parseString(), trying to modify it:

str[i] = '0';

Instead, in main() function you can do:

char str[] = "0123456789abcdef0123456789abcdef01234567";

which is equivalent to:

char str[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','0','1','2','3','4','5','6','7','\0'};

[Note the terminating null-character at the end.]

So, you can do:

#include <stdio.h>

void parseString(char *pstr)
{
    char * str = pstr;
    printf("%s\n", str);
    for(int i = 0; str[i] != '\0'; i++)
    {
        if(str[i] == 'a')
        {
            printf("%c\n", str[i]);
            str[i] = '0';
            printf("%c\n", str[i]);
        }
    }
    printf("%s\n", pstr);
}

int main(int argc, char *argv[])
 {
    char str[] = "0123456789abcdef0123456789abcdef01234567";
    parseString(str);
    printf("%s\n", str);
    return 0;
}

Note that in my program, I am only demonstrating the replacement of 'a' with '0' character. Hence, I removed typedef struct Int40... which exists in OP's code.