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

C语言结构体数组录入后无输出问题求助(附完整代码)

问题描述

我正在开发一个数据库项目的记录功能,需要创建由4个字符串组成的结构体数组,通过键盘录入数据后将这些记录打印出来,但程序无任何输出且未报错。

相关代码文件

main.c

#include <stdio.h>
#include "organs.h"

int main(){

    initMenu();
    int chosenOption = chooseOption(); //chosen option

    //working with chosen option
    switch (chosenOption){
        case 1:
            userKeyboardInput();
            break;
            //other cases not done yet
    }

}

organs.c

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

struct nn records[9];

void initMenu(){
    printf(" 1 - Input\n 2 - Output\n 3 - Add record\n 4 - Search\n 5 - Deleting\n 6 - Sort\n 7 - Exit\n");
}
int chooseOption(){
    printf("Choose option form 1 to 7:\n");
    int chosenOption;
    scanf("%d", &chosenOption);
    return chosenOption;
}

void userKeyboardInput(){
    printf("How many records do yo wish to make?\n");
    int noOfRecords;
    scanf("%d", &noOfRecords);
    int counter = 1;
    for(int x = 0; x < noOfRecords; x++){
        printf("%d record\n", counter);
        struct nn newRecord;
        for(int paramNO = 0; paramNO < 4; paramNO++){
            char symbol;
            char param[20];
            int i = 0;


            while(scanf("%c",&symbol) > 0 && (symbol!='\n' || i < 20)){
                param[i] = symbol;
                i++;
            }
            if(paramNO == 0){
                strcpy(newRecord.param1, param);
            }
            if(paramNO == 1){
                strcpy(newRecord.param2, param);
            }
            if(paramNO == 2){
                strcpy(newRecord.param3, param);
            }
            if(paramNO == 3){
                strcpy(newRecord.param4, param);
            }
        }
        records[x] = newRecord;
    }
    for(int x = 0; x < noOfRecords; x++){
        for(int i = 0; i < 10; i++){
            printf("%c", records[x].param1[i]);
        }
        printf ("  ");

        for(int i = 0; i < 10; i++){
            printf("%c", records[x].param2[i]);
        }
        printf ("  ");

        for(int i = 0; i < 10; i++){
            printf("%c", records[x].param3[i]);
        }
        printf ("  ");

        for(int i = 0; i < 10; i++){
            printf("%c", records[x].param4[i]);
        }
        printf ("  ");
    }
}

organs.h

#ifndef UNTITLED2_ORGANS_H
#define UNTITLED2_ORGANS_H

struct nn{
    char param1[20];
    char param2[20];
    char param3[20];
    char param4[20];
};
void initMenu();
int chooseOption();
void userKeyboardInput();

#endif //UNTITLED2_ORGANS_H

问题原因及修复方案

核心问题

  1. 输入缓冲区残留换行符:用scanf("%d", ...)读取数字后,输入时按下的换行符会留在缓冲区,后续scanf("%c")会直接读取这个换行符,导致第一个参数被错误赋值为空字符串,后续输入逻辑完全混乱。
  2. 字符读取循环条件错误:(symbol!='\n' || i < 20)逻辑错误,应为且的关系,同时要限制长度为19(留一个位置给字符串结束符'\0'),否则会超出数组边界,甚至无限读取。
  3. 未添加字符串结束符:读取字符到param数组后,没有手动添加'\0',导致strcpy操作读取垃圾数据,触发未定义行为。
  4. 打印逻辑冗余且不安全:循环打印前10个字符,不管字符串是否结束,可能输出垃圾字符。

修复后的userKeyboardInput函数

void userKeyboardInput(){
    printf("How many records do you wish to make?\n");
    int noOfRecords;
    scanf("%d", &noOfRecords);
    // 吃掉数字输入后的换行符
    getchar();
    
    int counter = 1;
    for(int x = 0; x < noOfRecords; x++){
        printf("%d record\n", counter++);
        struct nn newRecord;
        for(int paramNO = 0; paramNO < 4; paramNO++){
            char symbol;
            char param[20];
            int i = 0;

            // 修改循环条件:未到换行且未超过数组最大长度(留位置存'\0')
            while(scanf("%c", &symbol) > 0 && symbol != '\n' && i < 19){
                param[i] = symbol;
                i++;
            }
            // 添加字符串结束符
            param[i] = '\0';
            
            // 吃掉当前行剩余的换行符(防止影响下一次读取)
            if(symbol == '\n'){
                getchar();
            }

            switch(paramNO){
                case 0: strcpy(newRecord.param1, param); break;
                case 1: strcpy(newRecord.param2, param); break;
                case 2: strcpy(newRecord.param3, param); break;
                case 3: strcpy(newRecord.param4, param); break;
            }
        }
        records[x] = newRecord;
    }
    
    // 简化打印逻辑,直接输出字符串
    printf("\n录入的记录如下:\n");
    for(int x = 0; x < noOfRecords; x++){
        printf("%s  %s  %s  %s\n", 
               records[x].param1, 
               records[x].param2, 
               records[x].param3, 
               records[x].param4);
    }
}

额外优化点

  • 将多分支if替换为switch,代码更简洁。
  • 打印时直接使用%s格式符输出字符串,自动处理结束符,避免垃圾字符。
  • 修正拼写错误:yo改为you。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 19:48:12