我是C语言的新手。我想为我的代码创建一个数组来进行一些操作。正如我上面所说,我正在努力学习如何有效地使用C语言。我的问题是:我有一个输入文件,让我们说input.txt。我知道每一行都有4种不同的东西,其中2种是字符串,其中2种是数字。另外,我想创建一个2D数组。但我不知道输入文件中会有多少行。这取决于用户。所以,我必须使用 malloc 动态制作我的数组。那么,你能帮我解决这个问题吗?也许这很容易,但我认为读取文件并在C中创建一些数组比其他语言更难。在Python中它很容易:(我在下面留下我的代码。如果你告诉我我的错误,我会很高兴:)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[]) {
char *arrChar;
int i;
char *str;
char *token;
arrChar = (char *) malloc( sizeof( char ) );
str = (char *) malloc( sizeof( char ) );
FILE *FileChars;
FileChars = fopen( argv[1], "r");
i = 0;
while ( fgets(str, sizeof str, FileChars) != NULL) {
int j;
for ( j = 0; j < 4; j++ ) {
token = strtok(str, ",");
arrChar[i][j] = token;
}
i++;
}
}
答案 0 :(得分:1)
您需要准确理解sizeof
运算符的作用,它不会返回动态分配的内存块的大小,它会返回类型的大小,如果是数组 - 粗略地说 - 大小是类型规范的一部分,因此它返回数组占用的字节数。
在您的情况下,sizeof(char)
是char
类型的大小,(c-standard C标准<<{3}} C标准< 1 / em>的)。
sizeof(str)
是str
类型的大小,即char *
,即指针的大小。它可能是4
或8
,具体取决于您当前的平台。
要解决此问题,您必须在整个程序中定义一个长度,作为分配的内存块的长度,确保分配成功后(参见下面)
指向char
的指针可以指向一系列元素,如果它是正确的序列,则可以将其解释为字符串。一系列&#34; 可打印&#34;后跟'\0'
或 null 字符的字符被视为字符串。
如果您要处理相同的字符串,则必须在第一次之后将NULL
传递给strtok()
。
您应该通过将返回值与fopen()
进行比较来检查NULL
确实返回了有效的流。
与(5)相同,对于malloc()
,当分配不可能时NULL
被返回并将其用作有效指针未定义行为。< / p>
所有这一切,这就是你可能想写的东西
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_WORDS 100
int main(int argc, char const *argv[])
{
char *token;
char **words;
char line[100];
char *ptr;
size_t count;
FILE *file;
file = fopen( argv[1], "r");
// Check that we DID open the file
if (file == NULL) {
perror(argv[1]);
return EXIT_FAILURE;
}
// Allocate space for `NUM_WORDS' pointers
words = malloc(NUM_WORDS * sizeof(*words));
// Check that we did allocate enough memory
if (words == NULL) {
fclose(file);
return EXIT_FAILURE;
}
// We use `sizeof' here because `line' is an array
count = 0;
while ((count < NUM_WORDS) && (fgets(line, sizeof(line), file) != NULL)) {
ptr = line;
do {
token = strtok(ptr, ",");
// We need to copy the `token' because
// it lies within `line' and the '\0' will
// be replaced by the original character
// in subsequent callse to `strtok()'
//
// The `strdup()' will allocate enough space with
// `malloc()' then copy the contents of `token' to the
// allocated buffer, and return it, so we will
// have to call `free()' on every `words' element.
words[count++] = strdup(token);
// Subsequent calls to `strtok()' with the same
// string require that the first parameter is
// NULL
ptr = NULL;
} while ((count < NUM_WORDS) && (token != NULL));
}
// Now we may print the words and free the memory
for (size_t index = 0; index < count; ++index) {
puts(words[index]);
free(words[index]);
}
free(words);
return 0;
}
请注意,上面的代码确保我们不会超过指针数组words
1 的容量。如果您需要调整大小,则需要了解如何使用realloc()
并在专门的例程中执行此操作,以便您的代码不会变得过于复杂。
1 请注意,分配的空间没有预定义的解释,我们将其解释为数组,但它不是数组定义c意义上的数组, line
IS,具有类型char
,line的元素也可以被解释为字符串,因为它具有与上面第(2)点中给出的定义兼容的内容。