Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
130 views
in Technique[技术] by (71.8m points)

c - Program stops at for loop

I'm experimenting with C and trying to get used to memory and string stuff by creating a program that takes stdin in the form of words, processes the words, spits them back out and also tries changing the word's upper and lower cases.

However, it seems like the program doesn't execute anything beyond strcpy(key, word). It stops right at the for loop, and doesn't even execute the print statements after the loop.

So far, I've tried both a while loop and a for loop for the case changing. I made sure key copied correctly by printf'ing it on the line above the for loop. I even commented out the for loop and saw the tolower() call two lines worked and printed out the updated key. There's just something wrong with the for loop and I don't know what.

How would I be able to fix it?

int main(void)
{
    char ch; 
    char *word;
    word = (char *)malloc(60 * sizeof(char)); 
    int ind = 0; 
    int cap = 60; 
    while (ch = getchar()) { 
        if (isalnum(ch)) {
            if (ind >= cap) {
                word = (char *)realloc(word, (ind + 1) * sizeof(char));
                cap++; 
            }
            word[ind] = ch; 
            ind++; 
        } else {
            word[ind] = ''; 
            int size = strlen(word); 
            char key[size]; 
            strcpy(key, word); 
            for (int i = 0; i < size; i++) {
                if (i = 0) {
                    key[i] = toupper(key[i]);
                } else {
                    key[i] = tolower(key[i]);
                }
            }
            fprintf(stdout, "%s
", key);
            key[0] = tolower(key[0]);
            fprintf(stdout, "%s
", key);
            ind = 0; 
            memset(word, 0, sizeof word);
            putchar(ch); 
            putchar('
');
        }
    }
}
question from:https://stackoverflow.com/questions/66059743/program-stops-at-for-loop

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are multiple problems in your code:

  • ch must be defined with type int for proper detection of EOF. The return value of fgetc() can be a byte value (all values of type unsigned char) or the special negative value EOF. Converting to type char looses information.

  • while (ch = getchar()) cannot detect end of file, it only tests if the byte read from the file is non zero. You should write while ((ch = getchar()) != EOF).

  • you do not allocate space for the null terminator. More precisely, you should allow for 2 extra bytes when testing for the reallocation of the target buffer.

  • when reallocating the array, you should increase cap by more than 1 to avoid reallocating for each extra byte you need to store.

  • int size = strlen(word); can be replaced with int size = ind;.

  • char key[size]; is incorrect: you should allow for the null terminator by allocating one extra byte.

  • isalnum(), toupper(), tolower() and the other functions from <ctype.h> are only defined for all values returned by getchar(). Negative argument values different than EOF cause undefined behavior, a char argument must be cast as (unsigned char) to avoid undefined behavior on architectures where char is signed by default.

  • memset(word, 0, sizeof word); is useless.

  • you do not test for allocation failure.

  • you never free word.

Here is a modified version:

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

int main(void) {
    int ch; 
    int ind = 0; 
    int cap = 60;
    char *word = malloc(60); 

    if (word == NULL) {
        fprintf(stderr, "allocation failure
");
        return 1;
    }
    while ((ch = getchar()) != EOF) { 
        if (isalnum(ch)) {
            if (ind >= cap) {
                cap += cap / 2;
                word = realloc(word, cap);
                if (word == NULL) {
                    fprintf(stderr, "allocation failure
");
                    return 1;
                }
            }
            word[ind] = ch; 
            ind++; 
        } else {
            word[ind] = ''; 
            char key[ind]; 
            strcpy(key, word);
            if (ind > 0) {
                key[0] = toupper((unsigned char)key[0]);
                for (int i = 1; i < ind; i++) {
                    key[i] = tolower((unsigned char)key[i]);
                }
            }
            printf("%s
", key);
            key[0] = tolower((unsigned char)key[0]);
            printf("%s
", key);
            ind = 0;
            putchar(ch); 
            putchar('
');
        }
    }
    free(word);
    return 0;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...