簡體   English   中英

C 程序在給出正確的輸出后不會結束

[英]C Program doesn't end after giving the correct output

所以我正在嘗試做一個程序來讀取由空格和新行分隔的數字序列。 輸出應該是相同的序列,但刪除不必要的零(字符序列 'EOF' 結束程序)。 每個例子

  1. 01492 102934 應該是 1492 102934
  2. 9312 0 01923 應該是 9312 0 1923
  3. 0001249 0000 應該是 1249 0

好吧,我已經實現了這個目的,但遇到了一個障礙。 除非我輸入 EOF 序列,否則程序不會退出。 也許是因為我有一段時間(1)在運行,導致無限循環。 但是當我嘗試刪除它時,程序甚至根本不打印。 我還在學習這是一個學校項目。 任何幫助將不勝感激!

這是代碼:

#include <stdio.h>
int main(){
char c;
int i=0;
while(1){
    c=getchar();
    if (i==0){
        if(c=='0'){
            while (c=='0'){
            c=getchar();
            }
        }
        printf("%c",c);
        i=i+1;
    }
    else if (c==' '){
        printf("%c",c);
        c=getchar();
        if(c=='0'){
            while (c=='0'){
            c=getchar();
            }
        }
        printf("%c",c);
    }
    else if (c=='E'){
        c=getchar();
        if (c=='O'){
            c=getchar();
            if(c=='F'){
                printf("\n");
                return 0;
            }
        }
    }
    else{
        printf("%c",c);
    }
}

}

重要的東西:

int c; // IMPORTANT, cannot be char
while (1) {
    c = getchar();
    if (c == EOF) break; // exit loop
    // ...
}

必須有某種方式告訴程序退出。
這樣,程序將在字母x或兩個連續的換行符處退出或輸入END
當沒有任何東西可以從文件中讀取時, getchar將返回EOF 這可以在 Windows 上使用ctrl + z或 Linux 上的ctrl + dstdin (鍵盤)模擬。

#include <stdio.h>
#include <string.h>

int main ( void) {
    char done[4] = "";
    int c = 0;
    int prior = 0;
    int reading = 0;
    int zero = 1;

    while ( EOF != ( c = getchar ( )) && 'x' != c) {
        if ( '\n' == c && '\n' == prior) {
            break;
        }
        if ( c >= '0' && c <= '9') {
            reading = 1;
            if ( '0' != c) {
                zero = 0;
            }
            if ( ! zero) {
                putchar ( c);
            }
        }
        else {
            if ( reading) {
                if ( zero) {
                    putchar ( '0');
                }
                if ( ' ' == c || '\n' == c) {
                    putchar ( c);
                }
                else {
                    putchar ( ' ');
                }
            }
            reading = 0;
            zero = 1;
        }
        prior = c;

        done[0] = done[1];
        done[1] = done[2];
        done[2] = c;
        done[3] = 0;
        if ( 0 == strcmp ( done, "END")) {
            break;
        }
    }
    putchar ( '\n');
    return 0;
}
  1. getchar()返回一個整數,而不是一個字符。 如果它只返回一個字符,它就沒有辦法返回一個指示文件結束的值,因為所有字符值都是有效的,不能用於其他目的。

    十進制系統中的一個激勵示例可能是:檢查溫度的函數返回一個兩位數。 0 到 99 之間的任何溫度都是有效的。 溫度計斷線時如何報錯? 您必須返回一個具有更多位數的數字,並使用一個特殊值,例如UNPLUGGED = 100

    但 int 是一種更廣泛的類型:它比 char 具有更多的值,“額外”值可用於表示某些特殊情況,即“嘿,這不是一個有效字符,但我不得不告訴你的其他事情” .

  2. getchar()在失敗(任何失敗)時返回EOF常量,例如,如果沒有更多輸入可用。 即使失敗的原因不是輸入結束,你也無能為力。 您應該在第一個 EOF 處結束處理。

因此,將c的類型更改為 int,並且每次調用getchar() ,必須檢查其值是否為 EOF,並在遇到它時return

循環的嵌套結構意味着必須在整個地方重復 EOF 檢查。 有其他方法可以構造代碼以將這個檢查保存在一個地方,但是,無可否認,嵌套循環至少有利用分支預測器的潛力,而單個getchar后跟狀態機樣式的switch語句將使其成為可能表現可能更差。 在一個簡單的家庭作業問題中,這些都不重要,但需要牢記這一點。 在任何情況下,都必須對性能進行基准測試——別無他法。

試試這個代碼,我認為它符合你的要求:

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

static int getLine(char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf("%s", prmpt);
        fflush(stdout);
    }
    if (fgets(buff, sz, stdin) == NULL)
        return -2;
    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff) - 1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? -1 : 0;
    }
    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff) - 1] = '\0';
    return 0;
}

int* convert2numbers(char* arr, int size) {
    int i;
    int j;
    int k;

    char token[100];
    int* numbers;
    int last_space = 0;
    int index = 1;
    int amount = 1;
    // Count the amount of tokens.

    for (i = 0; i < size; ++i) {
        if (arr[i] == ' ') {
            ++amount;
        }
    }
    numbers = (int *)malloc(amount * sizeof(int));
    numbers[0] = amount;

    for (j = 0; j <= size; ++j) {
        if (arr[j] == ' ' || arr[j] == '\0') {

            // Copy token from input string.
            for (k = 0; k < j; ++k) {
                token[k] = arr[k + last_space];
            }
            token[j] = '\0';
            numbers[index] = atoi(token);
            // Clear the token and continue.
            memset(token, '\0', sizeof(token));
            last_space = j;
            ++index;
        }
    }
    return numbers;
}

int main(void) {
    int i;
    int size;
    int* numbers;
    int amount;
    char input[100];
    char help[] = "Numbers> ";

    printf("Input numbers below or press enter to exit!\n");
    while (1) {
        getLine(help, input, sizeof(input));
        // If input is empty exit.
        if (input[0] == '\0') {
            break;
        }
        size = strlen(input);
        numbers = convert2numbers(input, size);
        amount = numbers[0];
        for (i = 1; i < amount + 1; ++i) {
            printf("%d ", numbers[i]);
        }
        printf("\n");
    }
    return 0;
}

當使用這些輸入運行時,此代碼輸出:

Input numbers below or press enter to exit!
Numbers> 01492 102934
1492 102934
Numbers> 9312 0 01923
9312 0 1923
Numbers> 0001249 0000
1249 0

此外,如果您在控制台中按enter鍵,它會退出,以便輕松逃脫while(1)循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM