how to change single char in string array?

走远了吗. 提交于 2020-07-03 11:56:43

问题


Having this:

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

char *up(char *);

int main() {
    char initstr[20];
    printf("enter string\n");
    fgets(initstr, 20, stdin);

    char *str = up(initstr);
    printf("%s\n", str);
}

char *up(char *in) {
    char *ret;
    for (ret = in;
         *in != '\n'; 
         *(ret++) = toupper(*(in++))
        );
    return ret;
}

Run it as:

$./a.out
enter string
abc

#only new line from `printf("%s\n",str);`

From debugger

Hardware watchpoint 3: in

Old value = 0x7fffffffdc20 "abc\n"
New value = 0x7fffffffdc21 "bc\n"

Hardware watchpoint 2: ret

Old value = 0x7fffffffdc20 "abc\n"
New value = 0x7fffffffdc21 "bc\n"

Hardware watchpoint 3: in

Old value = 0x7fffffffdc21 "bc\n"
New value = 0x7fffffffdc22 "c\n"

Hardware watchpoint 2: ret

Old value = 0x7fffffffdc21 "bc\n"
New value = 0x7fffffffdc22 "c\n"
...

I can see that both variables are reducing, but I wanted to change the ret inline, char by char. But at the end (after loop), the ret is reduced to nothing, and the program will only output \n. So how can I achieve this in the loop head?

EDIT: Thanks to answer below, having in mind I have to return first address of pointer, I can implement loop_head-only function by this:

char *up(char *in){
    char *ret;
    size_t size=strlen(in);
    for(ret=in;
         *in!='\n'; 
         *(ret++)=toupper(*(in++))
        );
    return (ret-size+1);
}

回答1:


The bug in up is you increment ret all the way to the newline (\n) and return ret pointing to this character in the string. You should instead return a pointer to the initial character.

  • It is simpler to write this function using an index.
  • packing all the logic into the for clauses with an empty body is hard to read and error prone.
  • Note also that the string might not contain a newline, so it is safer to stop at the null terminator, the newline will not be changed by toupper().
  • Finally, you should not pass char values to toupper() because this function and all functions from <ctype.h> is only defined for values of type unsigned char and the special negative value EOF. On platforms where char is signed by default, the string might contain negative char values which may cause undefined behavior when passed to toupper(). Cast these as (unsigned char) to avoid this issue.

Here is a modified version:

#include <ctype.h>
#include <stdio.h>

char *up(char *s) {
    for (size_t i = 0; s[i] != '\0'; i++) {
         s[i] = toupper((unsigned char)s[i]);
    }
    return s;
}

int main() {
    char initstr[20];
    printf("enter string\n");
    if (fgets(initstr, sizeof initstr, stdin)) {
        char *str = up(initstr);
        printf("%s\n", str);
    }
    return 0;
}


来源:https://stackoverflow.com/questions/62233572/how-to-change-single-char-in-string-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!