Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
scanf和strtok对我来说工作不正常_C - Fatal编程技术网

scanf和strtok对我来说工作不正常

scanf和strtok对我来说工作不正常,c,C,我正在尝试编写一个基于菜单的小程序来维护记录。 用户输入用于存储总人数的数字(名字、姓氏、分数)。用户在一行中输入所有信息,用空格分隔,我将它们分成3列(名字、姓氏、分数),然后按enter键并继续输入更多信息,直到达到最大人数 我的问题是,当我运行它时,它不能正常工作;它运行并接受用户输入,但只针对两个学生(即使我在测试用例中使用了大于5的数字),然后程序立即结束(没有错误代码,只是结束了…),甚至没有进入菜单。有人能告诉我我的代码有什么问题吗 int i, j, count, numberP

我正在尝试编写一个基于菜单的小程序来维护记录。 用户输入用于存储总人数的数字(名字、姓氏、分数)。用户在一行中输入所有信息,用空格分隔,我将它们分成3列(名字、姓氏、分数),然后按enter键并继续输入更多信息,直到达到最大人数

我的问题是,当我运行它时,它不能正常工作;它运行并接受用户输入,但只针对两个学生(即使我在测试用例中使用了大于5的数字),然后程序立即结束(没有错误代码,只是结束了…),甚至没有进入菜单。有人能告诉我我的代码有什么问题吗

int i, j, count, numberPeople, temp, choice;
char people[15][3], tempArr[20];
char *token;

printf("Please indicate number of records you want to enter (min 5, max 15): ");
scanf("%d", &temp);

while ((temp > 15) || (temp < 5)) {
    printf("\nNumber not in specified range, try again.\n");
    printf("Please indicate number of records you want to enter (min 5, max 15): ");
    scanf("%d", &temp);
}


numberPeople = temp;


printf("\nEnter the first name, last name, and grade (put a space in between each): ");
    for (i = 0; i < numberPeople; i++) {
        fgets(tempArr, 20, stdin);

    token = strtok(tempArr, " ");

    for (j = 0; j < 3; j++) {
        while (token != NULL) {
            people[i][j] = *token;
            printf("%s\n", token); // this is here to as a test case to see if my data was being stored.
            token = strtok(NULL, " ");
        }
    }

}
首先,使用
fgets()
而不是
scanf()

接下来,您不需要for
(j=0;j首先,使用
fgets()
而不是
scanf()


接下来,您不需要for
(j=0;j一个问题是您正在使用
scanf()
读取整个输入行,该行在名字、姓氏和年级之间有空格:

for (i = 0; i < numberPeople; i++) {
    scanf("%s", tempArr);
}
但是正如@Pooya所指出的,这个字符串的大小对于你正在做的事情来说太小了。虽然你分配了学生和信息字段的二维数组,但是你从来没有分配字符串空间来保存他们的姓名和成绩:

char people[15][3]
如果在堆栈上执行此操作,则从概念上讲,它将成为第三个维度:

char people[15][3][24]
在此
scanf()
之后,缓冲区中仍保留一个返回字符:

scanf("%d", &temp);
它可能应该被清除。@KevinDTimm和@bruceg在这里暗示了一个问题:

for (j = 0; j < 3; j++) {
    while (token != NULL) {
        people[i][j] = *token;
否则,您的成绩字符串(最后一个字段)将有一个悬空的换行符。此外,您需要复制由
strtok()
返回的标记,不应直接存储它

将所有这些建议放在一起,并清理/修复我遇到的任何其他问题,我提供以下返工:

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

#define MINIMUM_STUDENTS 5
#define MAXIMUM_STUDENTS 15
#define DATA_FIELDS 3

#define MAXIMUM_LINE_LENGTH 100
#define MAXIMUM_DATA_LENGTH 50

int main(int argc, char **argv) {

    int numberPeople;
    char people[MAXIMUM_STUDENTS][DATA_FIELDS][MAXIMUM_DATA_LENGTH];

    printf("Please indicate number of records you want to enter (min %d, max %d): ", MINIMUM_STUDENTS, MAXIMUM_STUDENTS);

    scanf("%d", &numberPeople);

    while ((numberPeople < MINIMUM_STUDENTS) || (numberPeople > MAXIMUM_STUDENTS)) {
        printf("\nNumber not in specified range, try again.\n");
        printf("Please indicate number of records you want to enter (min %d, max %d): ", MINIMUM_STUDENTS, MAXIMUM_STUDENTS);
        scanf("%d", &numberPeople);
    }

    printf("\n");

    while ((getchar()) != '\n'); // flush the return (and anything else) after the number input above

    printf("Enter the first name, last name, and grade (put a space in between each): \n");

    for (int i = 0; i < numberPeople; i++) {
        char tempArr[MAXIMUM_LINE_LENGTH];

        fgets(tempArr, MAXIMUM_LINE_LENGTH, stdin);

        char *token = strtok(tempArr, " ");

        for (int j = 0; j < DATA_FIELDS && token != NULL; j++) {
            strncpy(people[i][j], token, MAXIMUM_DATA_LENGTH);

            // this is here to as a test case to see if my data was being stored.
            printf("%s\n", people[i][j]);

            token = strtok(NULL, " \r\n");
        }

    }

    // do what you need to do with the data here!

    return 0;
}
#包括
#包括
#包括
#定义至少5名学生
#定义最大学额15
#定义数据字段3
#定义最大线长度100
#定义最大数据长度50
int main(int argc,字符**argv){
整数人;
字符人物[最大学生数][数据字段][最大数据长度];
printf(“请指出您要输入的记录数(最小%d,最大%d):”,最小学生数,最大学生数);
scanf(“%d”和numberPeople);
而((人数<最低学生人数)| |(人数>最高学生人数)){
printf(“\n编号不在指定范围内,请重试。\n”);
printf(“请指出您要输入的记录数(最小%d,最大%d):”,最小学生数,最大学生数);
scanf(“%d”和numberPeople);
}
printf(“\n”);
while((getchar())!='\n');//在上面输入的数字之后刷新返回值(以及任何其他内容)
printf(“输入名字、姓氏和等级(在两者之间加空格):\n”);
for(int i=0;i
一个问题是您正在使用
scanf()
读取整个输入行,该行的名字、姓氏和年级之间有空格:

for (i = 0; i < numberPeople; i++) {
    scanf("%s", tempArr);
}
但是正如@Pooya所指出的,这个字符串的大小对于你正在做的事情来说太小了。虽然你分配了学生和信息字段的二维数组,但是你从来没有分配字符串空间来保存他们的姓名和成绩:

char people[15][3]
如果在堆栈上执行此操作,则从概念上讲,它将成为第三个维度:

char people[15][3][24]
在此
scanf()
之后,缓冲区中仍保留一个返回字符:

scanf("%d", &temp);
它可能应该被清除。@KevinDTimm和@bruceg在这里暗示了一个问题:

for (j = 0; j < 3; j++) {
    while (token != NULL) {
        people[i][j] = *token;
否则,您的成绩字符串(最后一个字段)将有一个悬空的换行符。此外,您需要复制由
strtok()
返回的标记,不应直接存储它

将所有这些建议放在一起,并清理/修复我遇到的任何其他问题,我提供以下返工:

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

#define MINIMUM_STUDENTS 5
#define MAXIMUM_STUDENTS 15
#define DATA_FIELDS 3

#define MAXIMUM_LINE_LENGTH 100
#define MAXIMUM_DATA_LENGTH 50

int main(int argc, char **argv) {

    int numberPeople;
    char people[MAXIMUM_STUDENTS][DATA_FIELDS][MAXIMUM_DATA_LENGTH];

    printf("Please indicate number of records you want to enter (min %d, max %d): ", MINIMUM_STUDENTS, MAXIMUM_STUDENTS);

    scanf("%d", &numberPeople);

    while ((numberPeople < MINIMUM_STUDENTS) || (numberPeople > MAXIMUM_STUDENTS)) {
        printf("\nNumber not in specified range, try again.\n");
        printf("Please indicate number of records you want to enter (min %d, max %d): ", MINIMUM_STUDENTS, MAXIMUM_STUDENTS);
        scanf("%d", &numberPeople);
    }

    printf("\n");

    while ((getchar()) != '\n'); // flush the return (and anything else) after the number input above

    printf("Enter the first name, last name, and grade (put a space in between each): \n");

    for (int i = 0; i < numberPeople; i++) {
        char tempArr[MAXIMUM_LINE_LENGTH];

        fgets(tempArr, MAXIMUM_LINE_LENGTH, stdin);

        char *token = strtok(tempArr, " ");

        for (int j = 0; j < DATA_FIELDS && token != NULL; j++) {
            strncpy(people[i][j], token, MAXIMUM_DATA_LENGTH);

            // this is here to as a test case to see if my data was being stored.
            printf("%s\n", people[i][j]);

            token = strtok(NULL, " \r\n");
        }

    }

    // do what you need to do with the data here!

    return 0;
}
#包括
#包括
#包括
#定义至少5名学生
#定义最大学额15
#定义数据字段3
#定义最大线长度100
#定义最大数据长度50
int main(int argc,字符**argv){
整数人;
字符人物[最大学生数][数据字段][最大数据长度];
printf(“请指出您要输入的记录数(最小%d,最大%d):”,最小学生数,最大学生数);
scanf(“%d”和numberPeople);
而((人数<最低学生人数)| |(人数>最高学生人数)){
printf(“\n编号不在指定范围内,请重试。\n”);
printf(“请指出您要输入的记录数(最小%d,最大%d):”,最小学生数,最大学生数);
scanf(“%d”和numberPeople);
}
printf(“\n”);
while((getchar())!='\n');//在上面输入的数字之后刷新返回值(以及任何其他内容)
printf(“输入名字、姓氏和等级(在两者之间加空格):\n”);
for(int i=0;i