Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中使用字符串数组数组解析文本文件_C_String_Matrix - Fatal编程技术网

在C中使用字符串数组数组解析文本文件

在C中使用字符串数组数组解析文本文件,c,string,matrix,C,String,Matrix,我想从N个文本文件中读取(具有类似的结构:几行,每行有相同的少量单词)并将读取的单词存储在字符串矩阵中,这样在每个(行、列)位置我都有一个单词 文件的简单样本(两行,每行三个单词)如下所示: line1word1 line1word2 line1word3 line2word1 line2word2 line2word3 单词的分隔符是空格 我尝试了以下代码: #include <math.h> #include <stdio.h> #include <stdli

我想从N个文本文件中读取(具有类似的结构:几行,每行有相同的少量单词)并将读取的单词存储在字符串矩阵中,这样在每个(行、列)位置我都有一个单词

文件的简单样本(两行,每行三个单词)如下所示:

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);