为什么在C中,当读取文件时,我们必须使用字符数组?

时间:2022-06-22 22:24:40

I've literally just started programming in C. Coming from a little understanding of Python.

我刚刚开始用c编程,对Python有一点了解。

Just had a lecture on C, the lecture was about this:

刚刚上了一堂关于C的课,讲的是

#include <stdio.h>

int main() {
    FILE *file;
    char name[10], degree[5];
    int mark;
    file = fopen("file.txt", "r");
    while (fscan(file("%s %s %d", name, degree, &mark) != EOF);
        printf("%s %s %d", name, degree, mark);
    fclose(file);
}

I'm specifically asking why we the lecturer would have used an array rather than just declaring two string variables. Searching for a deeper answer than just, "that's just C for you".

我特别想问为什么演讲者会使用数组而不是声明两个字符串变量。寻找一个更深层次的答案,而不仅仅是“这就是C”。

3 个解决方案

#1


3  

There are multiple typos on this line:

这一行有多个拼写错误:

while (fscan(file("%s %s %d", name, degree, &mark) != EOF);
    printf("%s %s %d", name, degree, mark);

It should read:

它应该阅读:

while (fscanf(file, "%s %s %d", name, degree, &mark) == 3)
    printf("%s %s %d", name, degree, mark);

Can you spot the 4 mistakes?

你能找出这4个错误吗?

  • The function is called fscanf
  • 这个函数叫做fscanf。
  • file is an argument followed by ,, not a function name followed by (
  • file是后跟参数的参数,而不是后跟(
  • you should keep looping for as long as fscanf converts 3 values. If conversion fails, for example because the third field is not a number, it will return a short count, not necessarily EOF.
  • 只要fscanf转换3个值,就应该保持循环。例如,如果转换失败,因为第三个字段不是数字,那么它将返回一个短计数,不一定是EOF。
  • you typed an extra ; after the condition. This is parsed as an empty statement: the loop keeps reading until end of file, doing nothing, and finally executes printf just once, with potentially invalid arguments.
  • 你多打了一份;后的状态。这被解析为一个空语句:循环一直读到文件结束,什么都不做,最后只执行一次printf,其中可能存在无效的参数。

The programmer uses char arrays and passes their address to fscanf. If he had used pointers (char *), he would have needed to allocate memory to make them point to something and pass their values to fscanf, a different approach that is not needed for fixed array sizes.

程序员使用char数组并将其地址传递给fscanf。如果他使用了指针(char *),他就需要分配内存,使它们指向某个东西,并将它们的值传递给fscanf,这是固定数组大小不需要的另一种方法。

Note that the code should prevent potential buffer overflows by specifying the maximum number of characters to store into the arrays:

注意,代码应该通过指定要存储到数组中的最大字符数来防止潜在的缓冲区溢出:

while (fscanf(file, "%9s %4s %d", name, degree, &mark) == 3) {
    printf("%s %s %d", name, degree, mark);
}

Note also that these hard-coded numbers must match the array sizes minus 1, an there is no direct way to pass the array sizes to fscanf(), a common source of bugs when the code is modified. This function has many quirks and shortcomings, use with extreme care.

还要注意,这些硬编码的数字必须匹配数组大小- 1,而且没有直接的方法将数组大小传递给fscanf(),这是代码修改时常见的bug来源。这个功能有许多怪癖和缺点,使用时要特别小心。

#2


1  

Take name[] for example. It's an array of chars, a collection of chars if you like.

以名称[]为例。它是一个chars数组,如果你喜欢,它是一个chars集合。

There is no string type in , so we use an array an array of chars when we want to use a string.

c中没有字符串类型,所以当我们想要使用字符串时,我们使用数组和字符数组。

The code is written as such, so that we can read the actual string in a line of the file, in our array.

代码是这样编写的,这样我们就可以在文件的一行中读取数组中的实际字符串。


As a side note, this program will produce syntax errors.

顺便说一下,这个程序会产生语法错误。

#3


0  

What you have in every non-empty file is a series of bytes. Therefor, what your C program has to do is read bytes. Since the variable type char is used to represent a byte, and since you want to read multiple bytes at once for efficiency purposes, you read an array of chars. That's for the general understanding of what reading from a file means.

您在每个非空文件中所拥有的是一系列字节。因此,C程序要做的就是读取字节。由于变量类型char用于表示一个字节,并且出于效率的目的,您希望一次读取多个字节,因此您需要读取一个chars数组。这是对从文件中读取内容的一般理解。

Going back to your example, there is no string type in C. A string is an array of bytes (char[]) ended by a nul character. What the lecturer is doing is:

回到您的示例,在c中没有字符串类型。字符串是以nul字符结尾的字节数组(char[])。讲师正在做的是:

  1. define an array of chars (which will contain a string) => char name[10] is an array that may contain a string of at most 9 characters (the last byte would be used for '\0').
  2. 定义一个chars数组(它将包含一个字符串)=> char name[10]是一个数组,它可能包含最多9个字符的字符串(最后一个字节将用于'\0')。
  3. ask fscanf to read a string, which means it will read multiple bytes (multiple chars) until it finds a nul character ('\0') and put all of that in the given array.
  4. 请求fscanf读取一个字符串,这意味着它将读取多个字节(多个字符),直到找到一个nul字符('\0')并将所有这些字符放入给定的数组中。

To understand what's happening, forget about string as an opaque data type (which might be true in other programming languages) and see them as what they really are: arrays of chars.

要理解正在发生的事情,请忘记字符串是不透明的数据类型(在其他编程语言中可能是这样),并将它们视为它们的真正含义:字符数组。

#1


3  

There are multiple typos on this line:

这一行有多个拼写错误:

while (fscan(file("%s %s %d", name, degree, &mark) != EOF);
    printf("%s %s %d", name, degree, mark);

It should read:

它应该阅读:

while (fscanf(file, "%s %s %d", name, degree, &mark) == 3)
    printf("%s %s %d", name, degree, mark);

Can you spot the 4 mistakes?

你能找出这4个错误吗?

  • The function is called fscanf
  • 这个函数叫做fscanf。
  • file is an argument followed by ,, not a function name followed by (
  • file是后跟参数的参数,而不是后跟(
  • you should keep looping for as long as fscanf converts 3 values. If conversion fails, for example because the third field is not a number, it will return a short count, not necessarily EOF.
  • 只要fscanf转换3个值,就应该保持循环。例如,如果转换失败,因为第三个字段不是数字,那么它将返回一个短计数,不一定是EOF。
  • you typed an extra ; after the condition. This is parsed as an empty statement: the loop keeps reading until end of file, doing nothing, and finally executes printf just once, with potentially invalid arguments.
  • 你多打了一份;后的状态。这被解析为一个空语句:循环一直读到文件结束,什么都不做,最后只执行一次printf,其中可能存在无效的参数。

The programmer uses char arrays and passes their address to fscanf. If he had used pointers (char *), he would have needed to allocate memory to make them point to something and pass their values to fscanf, a different approach that is not needed for fixed array sizes.

程序员使用char数组并将其地址传递给fscanf。如果他使用了指针(char *),他就需要分配内存,使它们指向某个东西,并将它们的值传递给fscanf,这是固定数组大小不需要的另一种方法。

Note that the code should prevent potential buffer overflows by specifying the maximum number of characters to store into the arrays:

注意,代码应该通过指定要存储到数组中的最大字符数来防止潜在的缓冲区溢出:

while (fscanf(file, "%9s %4s %d", name, degree, &mark) == 3) {
    printf("%s %s %d", name, degree, mark);
}

Note also that these hard-coded numbers must match the array sizes minus 1, an there is no direct way to pass the array sizes to fscanf(), a common source of bugs when the code is modified. This function has many quirks and shortcomings, use with extreme care.

还要注意,这些硬编码的数字必须匹配数组大小- 1,而且没有直接的方法将数组大小传递给fscanf(),这是代码修改时常见的bug来源。这个功能有许多怪癖和缺点,使用时要特别小心。

#2


1  

Take name[] for example. It's an array of chars, a collection of chars if you like.

以名称[]为例。它是一个chars数组,如果你喜欢,它是一个chars集合。

There is no string type in , so we use an array an array of chars when we want to use a string.

c中没有字符串类型,所以当我们想要使用字符串时,我们使用数组和字符数组。

The code is written as such, so that we can read the actual string in a line of the file, in our array.

代码是这样编写的,这样我们就可以在文件的一行中读取数组中的实际字符串。


As a side note, this program will produce syntax errors.

顺便说一下,这个程序会产生语法错误。

#3


0  

What you have in every non-empty file is a series of bytes. Therefor, what your C program has to do is read bytes. Since the variable type char is used to represent a byte, and since you want to read multiple bytes at once for efficiency purposes, you read an array of chars. That's for the general understanding of what reading from a file means.

您在每个非空文件中所拥有的是一系列字节。因此,C程序要做的就是读取字节。由于变量类型char用于表示一个字节,并且出于效率的目的,您希望一次读取多个字节,因此您需要读取一个chars数组。这是对从文件中读取内容的一般理解。

Going back to your example, there is no string type in C. A string is an array of bytes (char[]) ended by a nul character. What the lecturer is doing is:

回到您的示例,在c中没有字符串类型。字符串是以nul字符结尾的字节数组(char[])。讲师正在做的是:

  1. define an array of chars (which will contain a string) => char name[10] is an array that may contain a string of at most 9 characters (the last byte would be used for '\0').
  2. 定义一个chars数组(它将包含一个字符串)=> char name[10]是一个数组,它可能包含最多9个字符的字符串(最后一个字节将用于'\0')。
  3. ask fscanf to read a string, which means it will read multiple bytes (multiple chars) until it finds a nul character ('\0') and put all of that in the given array.
  4. 请求fscanf读取一个字符串,这意味着它将读取多个字节(多个字符),直到找到一个nul字符('\0')并将所有这些字符放入给定的数组中。

To understand what's happening, forget about string as an opaque data type (which might be true in other programming languages) and see them as what they really are: arrays of chars.

要理解正在发生的事情,请忘记字符串是不透明的数据类型(在其他编程语言中可能是这样),并将它们视为它们的真正含义:字符数组。