我使用循环和fget来运行这个输入文件。
CSCI112 Programming with C 3
CSCI127 Joy and Beauty of Data 4
CSCI132 Basic Data Structures and Algorithms 4
CSCI338 Computer Science Theory 3
CSCI215 Social and Ethical Issues in CS 3
ARCH112 Introduction to Design 3
COMX112 Interpersonal Skills in the Workplace 1
HSTA101 American History 4
XXXXXXX XXXXXX X我必须确定CSCI类的数量(以及其他事情,但这些并不重要)。目前,我使用的是一个类结构,它包含一个字符串ID、一个字符串名和一个int信用。
我的问题是,在我的类数组中,所有的ID都被存储为"XXXXXXX“。我不明白为什么for循环没有正确地为类分配值。
如果我运行这个程序,输出是
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-3
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-4
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-4
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-3
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-3
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-3
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-1
Class: ID-XXXXXXX, Name-XXXXXX X, Credits-4
CSCI classes: 0
CSCI class credits: 0显然,这些类是不正确的,而且CSCI数字也是错误的。我不明白如何正确分配学分,但ID和名字却不是?
这是我的代码:
#include <stdio.h>
#include <string.h>
#include "class.h"
int main(){
//variable declaration for classes
char line[100];
char line_copy[100];
char ccred;
class_t classes[100];
int i = 0;
//infinite loop
for(;;){
//read in input from file
fgets(line, sizeof(line), stdin);
strcpy(line_copy, line);
classes[i].ID = strtok(line, " ");
classes[i].name = strtok(NULL, "1234");
//remove trailing space from class name
classes[i].name[strlen(classes[i].name) - 1] = 0;
ccred = line_copy[strlen(line_copy) - 2];
classes[i].credits = ccred - '0';
//stop reading input if not a valid class
if(strcmp(classes[i].ID, "XXXXXXX") == 0){
break;
}
i++;
}
int ii;
for(ii = 0; ii < i; ii++){
printf("Class: ID-%s, ", classes[ii].ID);
printf("Name-%s, ", classes[ii].name);
printf("Credits-%d\n", classes[ii].credits);
}
//find CSCI classes and credits only
int CSCIclasses = 0;
int CSCIcredits = 0;
char toCompare[] = "CSCI";
int k;
for(k = 0; k < i; k++){
if(strncmp(toCompare, classes[k].ID, 4) == 0){
printf("CSCI course!");
CSCIclasses++;
CSCIcredits += classes[k].credits;
}
}
printf("CSCI classes: %d\n", CSCIclasses);
printf("CSCI class credits: %d\n", CSCIcredits);
return 0;
}我的问题是:如何正确地分配类结构的值并获得适当数量的CSCI类和学分?
谢谢你的帮助!
发布于 2018-04-06 03:40:22
strtok函数返回指向要标记的缓冲区的指针。这意味着所有结构的所有ID和name指针都指向同一个line数组。
您可以使用malloc和strcpy的动态分配来复制字符串(或者通用但非C标准的strdup函数)。或者对结构中的字符串使用数组(和strcpy)。
发布于 2018-04-06 05:23:29
虽然您现在了解到,line和您所做的任何复制,或者引用line中某个地址的任何指针,都将指向line中在read循环末尾的最终内容,但是您接下来可能会遇到由于name中的空格而试图标记每一行的问题。
虽然可以使用strtok,在'space'上保存每个前一个指针,然后使用前一个指针作为name的结束指针,但是简单地使用strchr查找第一个空格,使用strrchr来设置指向nul-char的指针(或者使用strlen将指针设置为结束字符),然后使用备份查找最后一个'space'则容易得多。这样,您知道第一个空格和最后一个空格之间的所有内容都是name,最后一个空格之后的字符是credits。这使得处理起来相当简单。
总之,您可以这样做:为credits使用一个固定数组(您知道这是6-chars ),并为name分配存储空间,并消除line_copy沿行遍历指针,选择所需的内容并不会修改line。
#include <stdio.h>
#include <stdlib.h> /* for malloc/free */
#include <string.h>
// #include "class.h"
#define MAXID 8 /* maximum ID, characters & structs */
#define MAXC 128 /* if you need constants, define them */
#define MAXS MAXC /* (don't use magic numbers) */
typedef struct {
char ID[MAXID], /* fixed 8 chars for 6 + 1 needed for ID */
*name, /* you must allocate storage for name */
credits;
} class_t;
int main(){
char line[MAXC] = "", /* variable declaration for classes */
*toCompare = "CSCI"; /* CSCI classes and credits only */
int CSCIclasses = 0,
CSCIcredits = 0,
i, n = 0;
size_t maxlen = 0;
class_t classes[MAXS] = {{ .ID = "" }};
for (; n < MAXS; ) { /* loop continually for input */
char *p = line, /* pointer to line */
*ep = NULL; /* end pointer for line */
if (!fgets (line, sizeof(line), stdin)) /* read/validate line */
break;
ep = strchr (line, ' '); /* set end pointer to 1st space */
if (ep) { /* validate 1st space found */
size_t len = ep - p; /* get length of ID */
if (len > MAXID - 1) { /* validate it fits + nul-char */
fprintf (stderr, "error: ID exceeds MAXID.\n");
return 1;
}
strncpy (classes[n].ID, p, len); /* copy ID */
classes[n].ID[len] = 0; /* nul-terminate ID */
}
else
continue; /* get next line */
p = ep + 1; /* set pointer to start of name */
ep = strrchr (line, 0); /* set end pointer to nul-character */
while (ep > p && *ep != ' ') /* backup to last space */
ep--;
if (*ep == ' ') { /* if space, parse remainder o fline */
size_t len = ep - p; /* len of name */
if (!(classes[n].name = malloc (len + 1))) { /* allocate */
perror ("malloc-classes[].name");
break;
}
ep++; /* move end pointer to credits */
strncpy (classes[n].name, p, len); /* copy to name */
classes[n].name[len] = 0; /* nul-termiante name */
if ('0' <= *ep && *ep <= '9') /* is credits digit? */
classes[n++].credits = *ep - '0'; /* assign credits */
else
classes[n++].credits = 0; /* set credits zero */
if (len > maxlen)
maxlen = len;
}
}
for (i = 0; i < n; i++) /* output class information */
printf ("Class: ID-%s, Name-%s, %-*s Credits-%d\n", classes[i].ID,
classes[i].name, (int)(maxlen - strlen(classes[i].name) + 1),
" ", classes[i].credits);
putchar ('\n'); /* tidy up with newline */
for (i = 0; i < n; i++) { /* output CSCI courses, free memory */
if (strncmp (toCompare, classes[i].ID, 4) == 0) {
printf("CSCI course! - %s\n", classes[i].name);
CSCIclasses++;
CSCIcredits += classes[i].credits;
}
free (classes[i].name); /* free 'name' - no longer needed */
}
printf ("CSCI classes: %d\n", CSCIclasses); /* output CSCI summary */
printf ("CSCI class credits: %d\n", CSCIcredits);
return 0;
}(注意:常量的定义。如果您需要一个(或多个) #define,或者使用enum来完成它。不要在代码中撒满像100这样的神奇数字。在顶部定义它们,因此,如果您的需求发生变化,您可以在一个简单的地方进行更改,其余的将自动处理)
示例使用/输出
$ ./bin/classes <dat/classes.txt
Class: ID-CSCI112, Name-Programming with C, Credits-3
Class: ID-CSCI127, Name-Joy and Beauty of Data, Credits-4
Class: ID-CSCI132, Name-Basic Data Structures and Algorithms, Credits-4
Class: ID-CSCI338, Name-Computer Science Theory, Credits-3
Class: ID-CSCI215, Name-Social and Ethical Issues in CS, Credits-3
Class: ID-ARCH112, Name-Introduction to Design, Credits-3
Class: ID-COMX112, Name-Interpersonal Skills in the Workplace, Credits-1
Class: ID-HSTA101, Name-American History, Credits-4
Class: ID-XXXXXXX, Name-XXXXXX, Credits-0
CSCI course! - Programming with C
CSCI course! - Joy and Beauty of Data
CSCI course! - Basic Data Structures and Algorithms
CSCI course! - Computer Science Theory
CSCI course! - Social and Ethical Issues in CS
CSCI classes: 5
CSCI class credits: 17仔细看一看,如果你还有什么问题,请告诉我。
https://stackoverflow.com/questions/49684884
复制相似问题