在C中使用字符串数组数组解析文本文件
我想从N个文本文件中读取(具有类似的结构:几行,每行有相同的少量单词)并将读取的单词存储在字符串矩阵中,这样在每个(行、列)位置我都有一个单词 文件的简单样本(两行,每行三个单词)如下所示:在C中使用字符串数组数组解析文本文件,c,string,matrix,C,String,Matrix,我想从N个文本文件中读取(具有类似的结构:几行,每行有相同的少量单词)并将读取的单词存储在字符串矩阵中,这样在每个(行、列)位置我都有一个单词 文件的简单样本(两行,每行三个单词)如下所示: line1word1 line1word2 line1word3 line2word1 line2word2 line2word3 单词的分隔符是空格 我尝试了以下代码: #include <math.h> #include <stdio.h> #include <stdli
line1word1 line1word2 line1word3
line2word1 line2word2 line2word3
单词的分隔符是空格
我尝试了以下代码:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_LENGTH 1000
#define MAX_TOKS 100
#define DELIMITERS " "
// line parsing utility
int parseString(char* line, char*** argv) {
char* buffer;
int argc;
buffer = (char*) malloc(strlen(line) * sizeof(char));
strcpy(buffer,line);
(*argv) = (char**) malloc(MAX_TOKS * sizeof(char**));
argc = 0;
(*argv)[argc++] = strtok(buffer, DELIMITERS);
while ((((*argv)[argc] = strtok(NULL, DELIMITERS)) != NULL) &&
(argc < MAX_TOKS)) ++argc;
return argc;
}
int main() {
char S[MAX_STRING_LENGTH];
char **A;
int n,i,j,l;
FILE *f;
char file[50];
char ***matrix;
matrix = malloc(MAX_TOKS * sizeof(char**));
//memory allocation for matrix
for (i = 0; i < MAX_TOKS; i++)
{
matrix[i] = malloc(MAX_TOKS * sizeof(char *));
for (j = 0; j < MAX_TOKS; j++)
{
matrix[i][j] = malloc(MAX_TOKS * sizeof(char));
}
}
int NFILE = 10; // number of files to be read
for(i=0;i<NFILE;i++)
{
sprintf(file,"file%d.txt",i);
f = fopen(file,"r");
l=0; // line-in-file index
while(fgets(S,sizeof(S),f)!=NULL) {
n = parseString(S,&A);
for(j=0;j<n;j++) {
matrix[i][l]=A[j];
printf("%s\t%s\n",matrix[i][l],A[j]);
}
l++;
}
fclose(f);
}
free(matrix);
free(A);
return(0);
}
我发现每行的最后一个字(并且只有最后一个字),不管文件号如何,都不会存储在矩阵中。也就是说,file0
的line1word1
和line1words
被正确地存储在matrix[0][0][0]
和matrix[0][0][1]
中,但是在matrix[0][0][2]
字段中没有line1word3
,即使A[2]
有它
我在干什么?有什么建议吗
多谢各位,
cheers字符***矩阵
不声明三维数组。您的矩阵需要类似于char*matrix[a][b]
来保存字符串指针的二维数组。为了计算数组中的地址,编译器需要知道除一个维度以外的所有维度。如果你仔细想想,你可能会明白为什么
如果有两个阵列:
1 2 3 1 2 3 4 5 6 7
4 5 6 8 9 10 11 12 13 14
7 8 9 15 16 17 18 19 20 21
您可以看到项[1][1]
不是同一项。不管数组中的维度如何,元素通常在内存中按顺序排列,每一行都在前一行(或者可能的列,我想这取决于语言)之后。如果有指针数组,实际内容可能在别处,但点的排列方式是这样的。因此,在我上面的示例中,您必须向编译器提供列数,以便它可以找到成员(行数可以是可变的)。在三维数组中,您必须提供前两个维度,以便编译器可以计算项偏移量
我希望这有帮助
编辑:通过创建自己的函数来处理所有数组项访问,您可以拥有真正的动态数组维度。函数需要知道动态维度和项索引,以便计算适当的地址。这看起来是错误的:
buffer=(char*)malloc(strlen(line)*sizeof(char))代码>
首先,不需要在C中强制转换malloc。如果您的代码没有强制转换就无法编译,可能有两个原因:
malloc没有原型。显然,这会导致问题,因为没有原型意味着函数返回默认类型:int
,否则会发生错误。这可能会导致程序行为不当。为了避免这种情况,请包括
你使用的是C++编译器。停止或者C++中的程序(停止使用Maloc)或者使用C编译器。如果你想在C++项目中使用这个项目,请用C编译器编译C代码,并在C++编译器中链接到它。
其次,sizeof(char)总是1。没有必要乘以它
第三,字符串是以第一个“\0”结尾的字符序列。这意味着字符串始终至少占用1个字符,即使它是空字符串。strlen(“”)返回什么?什么是(“”
?您需要添加1来为“\0”腾出空间:buffer=malloc(strlen(line)+1)代码>
这看起来有点错误:(*argv)=(char**)malloc(MAX_TOKS*sizeof(char**))代码>
malloc返回指向对象的指针*argv
是一个char**
,这意味着它指向一个char*
。但是,在本例中,malloc返回指向char**
对象的指针。表示形式不要求完全相同。为了避免与此相关的可移植性问题,请遵循以下模式variable=malloc(n*sizeof*variable)代码>。。。在这种情况下,*argv=malloc(MAX_TOKS***argv)代码>
它越走越硬。忘记所有你认为你知道的关于你的代码的事情;假装你会在24个月后回到这里。你会怎么想
argc = 0;
(*argv)[argc++] = strtok(buffer, DELIMITERS);
while ((((*argv)[argc] = strtok(NULL, DELIMITERS)) != NULL) &&
(argc < MAX_TOKS)) ++argc;
问题在于,当strtok返回NULL时,解析循环不会增加。因此,函数返回最后一项的位置。假设您有两个令牌,解析函数将返回1。您的显示循环显示的项目最多可显示,但不包括此位置:for(j=0;j解析子程序是我在Program-10中找到的,非常感谢您的帮助。我真的通读了一遍,并根据您的建议更改了代码,但问题没有解决:每行的最后一个字没有存储,我无法回忆起。(顺便说一句,我想+1你的答案,但我没有足够的分数来获得这个特权,对不起)@CarloAlberto:我在你的问题中没有看到对代码的任何更改。如果你不给我看新代码,我如何验证你已经对我看到的问题进行了更正,并且更正不会引起更多问题?我如何帮助你处理我看不到的代码?请更新你的问题。
argc = 0;
(*argv)[argc++] = strtok(buffer, DELIMITERS);
while ((((*argv)[argc] = strtok(NULL, DELIMITERS)) != NULL) &&
(argc < MAX_TOKS)) ++argc;
char *arg;
size_t argc = 0;
do {
arg = strtok(buffer, DELIMITERS);
buffer = NULL;
(*argv)[argc] = arg;
argc++;
} while (argc < MAX_TOKS && arg != NULL);