输入
name number number
就像例子
bank 1 10
我需要将输入读入矩阵n行3列,如下一个示例
{ bank, 1, 10,
bank2, 2, 15,
bank3, 3, 20 }
我的主要困难是阅读名称并存储到矩阵中。名称可以在1到41个字符之间变化。
我尝试按以下方式进行操作,但我不知道如何忽略输入中的空格以及如何使for
循环仅计数直到读取该单词。
for (b=0; b<41;b++) {
scanf("%s ",&nome[i]);
}
scanf("%d %d",&rating,&ref);
n[i][0] = *nome;
n[i][1] = rating;
n[i][2] = ref;
我刚开始用C学习编程,所以我不能在代码中使用高级内容。
答案 0 :(得分:1)
您尝试一次读取一个字符串,但使用编辑描述符读取整个字符串。你试图让它变得比它需要的更难。
此外,术语“矩阵”通常被理解为表示所有相同类型的元素的二维数组,而听起来您想要包含不同类型成员的struct
的一维数组。例如:
#define MAX_BANKS 10
struct bank {
char nome[42];
int rating;
int ref;
};
struct bank banks[MAX_BANKS];
int num_banks = 0;
/* ... */
void read_banks(void) {
while (num_banks < MAX_BANKS) {
int fields;
fields = scanf("%41s %d %d", banks[num_banks].nome,
&banks[num_banks].rating, &banks[num_banks].ref);
if (fields != 3) {
/* handle error */
break;
} else {
num_banks += 1;
}
/* ... */
}
}
答案 1 :(得分:0)
在这个例子中,我已经解释了你的&#34;矩阵&#34;要求,使得输入的每一行填充具有不同字段类型的struct
,因此我们最终得到struct
的1-D数组,而不是不同数据类型的2-D数组
而不是从键盘输入数据,这在每次测试程序时都很无聊,我把数据放在一个文件中并从中读取 - 虽然技术非常相似。
此外,由于您的输入格式不一致,我已跳过任何不构成数据一部分的字符,请参阅delims
。
该程序可能比您希望的更复杂,但我希望它能帮助您做您想做的事情。当我决定不在struct
中使用固定长度的字符串,而是指向字符串内存的指针(为可变长度字符串分配)时,复杂程度会上升。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char *nome;
int rating;
int ref;
} customer;
void fatal(char *msg) {
printf("%s\n", msg);
exit (1);
}
int main()
{
FILE *fp; // for fopen
char line[1000]; // for fgets
char *delims = ", {}\t\r\n"; // for strtok
char *sptr; // for strtok
customer *mark = NULL; // an empty array
int marks = 0; // number of customers
int len; // length of input string
fp = fopen("input.txt", "r"); // open the file
if (fp == NULL) // did it open?
fatal("Cannot open file");
while (fgets(line, 1000, fp) != NULL) { // each line of file
mark = realloc(mark, sizeof(customer) * (marks+1)); // extend
if (mark == NULL)
fatal("Cannot extend array"); // failed extend the array
sptr = strtok(line, delims); // split first field
if (sptr == NULL)
fatal("Cannot get first field");
len = strlen(sptr); // length of bank name
mark[marks].nome = malloc(len+1); // memory for the string
if (mark[marks].nome == NULL)
fatal("Cannot allocate string array");
strcpy(mark[marks].nome, sptr); // copy string to struct
sptr = strtok(NULL, delims); // split second field
if (sptr == NULL)
fatal("Cannot get second field");
mark[marks].rating = atoi(sptr); // extract number
sptr = strtok(NULL, delims); // split third field
if (sptr == NULL)
fatal("Cannot get third field");
mark[marks].ref = atoi(sptr); // extract number
marks++; // one more record
}
fclose (fp);
// print the results (re-using len for convenience)
for (len=0; len<marks; len++)
printf("%s %d %d\n", mark[len].nome, mark[len].rating, mark[len].ref);
// release the data array
for (len=0; len<marks; len++)
free(mark[len].nome);
free(mark);
return 0;
}
输入文件:
{ bank, 1, 10,
bank2, 2, 15,
bank3, 3, 20 }
节目输出:
bank 1 10
bank2 2 15
bank3 3 20
答案 2 :(得分:0)
由于您正在处理不同类型信息的集合(例如char*
,int
,int
),因此收集此信息的正确方法是在结构中(或{ {1}})。关于如何为任何数组或结构数组创建空间,您有两种选择:(1)在堆栈上静态分配,或(2)在堆上动态分配。鉴于您的问题要求,静态分配是最基本的。但是,它不像动态分配数据那样灵活,而且您只能选择初始大小。
与存储数据一样,您可以选择如何从struct
读取数据。作为一般命题,当从stdin
读取时,首选方法是一次读取一行到缓冲区,然后解析缓冲区以获得所需内容。如上所述,行输入比将数据压缩为stdin
格式字符串更灵活,但更复杂一些。出于此目的,我们将使用scanf
,但请注意,使用scanf
或getline
的行输入可提供某些优势。
接下来,您可以只声明所需的结构数,或者可以花时间初始化每个结构中的所有值。 (这有你的优点,如下所示)。除了允许一些迭代技巧之外,初始化所有变量的主要原因是为了防止未初始化读取它们的可能性。读取未初始化的变量会导致未定义的行为(fgets
)。因此,请花点时间学习如何初始化每个变量类型。
话虽如此,你可以说有很多有效的方法可以解决任何问题。只要你正确地做到了,你如何做到这一点取决于你。这是另一种满足您要求的方法。请注意,代码顶部定义了最大名称长度bad
和最大行数MAXNM
。这使您可以在以后轻松调整值。如果您有任何问题,请与我联系:
MAXLN
<强>输入强>
#include <stdio.h>
#define MAXNM 41
#define MAXLN 100
typedef struct mix {
char name[MAXNM + 1];
int num1;
int num2;
} mix;
int main (void) {
/* initialize array of structs & variables */
mix array[MAXLN] = {{ {0}, 0, 0 }};
size_t i = 0;
size_t read = 0;
/* read array of struct contents from stdin */
while (scanf ("%s %d %d", array[i].name, &array[i].num1, &array[i].num2) == 3) {
i++;
/* check if lines > MAXLN allowed */
if (i >= MAXLN) {
fprintf (stderr, "warning: lines read from stdin exceed MAXLN.\n");
break;
}
}
/* set the number of elements read to i */
read = i;
/* iterate over elements using 'read' */
printf ("\nIterating array using 'while (i < read)'\n\n");
i = 0;
while (i < read) {
printf (" array[%zu] %-41s %4d %4d\n", i, array[i].name, array[i].num1, array[i].num2);
i++;
}
/* iterate over array by virtue of initization of name to 0/null */
i = 0;
printf ("\nIterating array using 'while (array[i].name[0])'\n\n");
while (array[i].name[0]) {
printf (" array[%zu] %-41s %4d %4d\n", i, array[i].name, array[i].num1, array[i].num2);
i++;
}
printf ("\n");
return 0;
}
<强>输出强>
$ ./bin/ptrarraystatic< DAT / staticstruct.txt
$ cat dat/staticstruct.txt
TheNamesofVaryingWidth 123 456
SomeOtherName 234 567
Bank_1 12 34
Bank_2 23 45
Bank_3 34 56
OneLastNameThatHasCloseToTheMaximumChars 777 9999