You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

M1芯片MacBook上C代码EOF触发后循环异常问题(Xcode/Terminal)

M1 Mac下C语言代码输入EOF后终端循环输出异常

在搭载M1芯片的MacBook上运行以下C语言代码时,执行编辑文件操作并按Ctrl+D发送EOF信号后,文件编辑成功,但终端会反复循环输出菜单和编辑提示:

Menu:

  1. Display file
  2. Edit file
  3. Create new file
  4. Exit
    Choice: Enter the new text (end with Ctrl+D in Unix or Ctrl+Z in Windows):

问题原因

按下Ctrl+D时,stdin被标记为EOF状态。后续main函数中的scanf("%d", &choice)会读取失败,choice的值保持上一次的输入(即2,对应编辑文件选项),从而无限循环执行editFileContents函数。

解决方案

需要在编辑操作完成后清除stdin的EOF标记,同时处理scanf读取失败的情况,避免choice值残留。

修改后的完整代码

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

#define MAX_FILENAME_LENGTH 256
#define MAX_TEXT_LENGTH 1024

void deleteFile(char *filename){
    if (remove(filename) == 0) {
        printf("File %s deleted:\n", filename);
    } else {
        perror("Could not delete the file");
    }
}

void displayFileContents(char *filename) {
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        printf("Could not open the file '%s'\n", filename);
        return;
    }

    char line[MAX_TEXT_LENGTH];
    while (fgets(line, sizeof(line), file) != NULL) {
        printf("%s", line);
    }

    fclose(file);
}

void editFileContents(char *filename) {
    FILE *file = fopen(filename, "a+");
    if (file == NULL) {
        printf("Could not open the file '%s'\n", filename);
        return;
    }

    char newContents[MAX_TEXT_LENGTH];
    printf("Enter the new text (end with Ctrl+D in Unix or Ctrl+Z in Windows):\n");

    while (fgets(newContents, sizeof(newContents), stdin) != NULL) {
        size_t len = strlen(newContents);
        if (len > 0 && newContents[len - 1] == '\n') {
            newContents[len - 1] = '\0';
        }
        fprintf(file, "%s\n", newContents);
    }

    // 清除stdin的EOF标记,恢复输入功能
    clearerr(stdin);
    fclose(file);
}

int createNewFile(char *filename) {
    FILE *file = fopen(filename, "r");
    if (file != NULL) {
        printf("File already exists\n");
        fclose(file);
        return 0; // out of createFile
     }
    else {
        FILE *file = fopen(filename, "w");
        if (file == NULL) {
            printf("Could not create the file '%s'\n", filename);
            return 1; // out of createFile
        }
        fclose(file);
    }
    editFileContents(filename);
    return 2;
}

int main() {
    char filename[MAX_FILENAME_LENGTH];
    printf("Enter the filename to work on\n");
    scanf("%s", filename);

    int choice;

    while (1){
        printf("\nMenu:\n");
        printf("1. Display file\n");
        printf("2. Edit file\n");
        printf("3. Create new file\n");
        printf("4. Exit\n");
        printf("Choice: ");
        
        // 处理scanf读取失败的情况,重置choice并清除输入缓冲区
        if (scanf("%d", &choice) != 1) {
            choice = -1; // 设置为无效选项,触发default提示
            // 清除stdin中残留的字符,避免影响下一次输入
            int c;
            while ((c = getchar()) != '\n' && c != EOF);
        }

        switch (choice) {
            case 1:
                displayFileContents(filename);
                break;
            case 2:
                editFileContents(filename);
                break;
            case 3:
                createNewFile(filename);
                break;
            case 4:
                printf("Exiting...\n");
                return 0;  // out of main()
            default:
                printf("Invalid choice. Try again.\n");
        }
    }
}

关键修改点

  • 在editFileContents函数末尾添加clearerr(stdin),清除stdin的EOF标记,让后续输入操作恢复正常。
  • 在main函数中增加scanf读取失败的判断:若读取失败,将choice设为无效值,并清空输入缓冲区的残留字符,避免影响下一次菜单选择。

内容的提问来源于stack exchange,提问作者N1MA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 17:40:32