Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.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_Arrays_File - Fatal编程技术网

C 拆分从文件中读取的字符串

C 拆分从文件中读取的字符串,c,arrays,file,C,Arrays,File,我有一个这样的文件 GET /index.html k GET /docencia.html k GET /ejemplo.html k 我想一行一行地读它,然后用这个分隔符把它分开,但是给了我一个错误:分段错误(内核转储),我不知道该怎么做 这是我的代码: #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char ordenes[150]; char

我有一个这样的文件

GET /index.html k
GET /docencia.html k
GET /ejemplo.html k
我想一行一行地读它,然后用这个分隔符把它分开,但是给了我一个错误:
分段错误(内核转储)
,我不知道该怎么做

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    char ordenes[150];
    char *orden[3];
    char *token;
    int tok;

    FILE *fp;
    fp = fopen(argv[1], "r");
    if (fp == NULL) {
        printf("File error");
        exit(1);
    }

    while (feof(fp) == 0) {
        fgets(ordenes, sizeof(ordenes), fp);
        printf("%s \n", ordenes);
        token = strtok(ordenes, " ");
        tok = 0;
        while (token != NULL) {
            orden[tok] = strdup(token);
            tok++;
            token = strtok(NULL, " ");
        }

        printf("\n%s\n", orden[0]);
        printf("\n%s\n", orden[1]);
        printf("\n%s\n", orden[2]);
    }
    fclose(fp);
}
#包括
#包括
int main(int argc,char*argv[]){
半焦烯[150];
char*orden[3];
字符*令牌;
int tok;
文件*fp;
fp=fopen(argv[1],“r”);
如果(fp==NULL){
printf(“文件错误”);
出口(1);
}
while(feof(fp)==0){
fgets(ordenes,sizeof(ordenes),fp);
printf(“%s\n”,ordenes);
令牌=strtok(ordenes,“”);
tok=0;
while(令牌!=NULL){
orden[tok]=strdup(令牌);
tok++;
令牌=strtok(空,“”);
}
printf(“\n%s\n”,orden[0]);
printf(“\n%s\n”,orden[1]);
printf(“\n%s\n”,orden[2]);
}
fclose(fp);
}
调用第一个
strdup
时显示错误。如果我在调用第一个
strtok
后尝试打印令牌,它也会失败(相同的
分段错误内核转储了
),因此我猜问题出在
strtok
上,请尝试以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    char ordenes[150];
    char *orden[3];
    char *token;
    int tok;
    FILE *fp;

    fp = fopen (argv[1], "r");
    if(fp==NULL){
        printf("File error");
        exit(1);
    }
    while(fgets(ordenes, sizeof(ordenes), fp)){
        printf("%s\n",ordenes);
        token = strtok(ordenes, " ");
        tok = 0;
        while (token != NULL){
            orden[tok++] = strdup(token);
            token = strtok(NULL," ");
        }
        printf("\n%s\n",orden[0]);
        printf("\n%s\n",orden[1]);
        printf("\n%s\n",orden[2]);
        free(orden[0]);free(orden[1]);free(orden[2]);
    }
    fclose(fp);
}
#包括
#包括
#包括
int main(int argc,char*argv[]){
半焦烯[150];
char*orden[3];
字符*令牌;
int tok;
文件*fp;
fp=fopen(argv[1],“r”);
如果(fp==NULL){
printf(“文件错误”);
出口(1);
}
while(fgets(ordenes,sizeof(ordenes,fp)){
printf(“%s\n”,ordenes);
令牌=strtok(ordenes,“”);
tok=0;
while(令牌!=NULL){
orden[tok++]=strdup(令牌);
令牌=strtok(空,“”);
}
printf(“\n%s\n”,orden[0]);
printf(“\n%s\n”,orden[1]);
printf(“\n%s\n”,orden[2]);
自由(奥登[0]);自由(奥登[1]);自由(奥登[2]);
}
fclose(fp);
}
试试这个:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]){
    char ordenes[150];
    char *orden[3];
    char *token;
    int tok;
    FILE *fp;

    fp = fopen (argv[1], "r");
    if(fp==NULL){
        printf("File error");
        exit(1);
    }
    while(fgets(ordenes, sizeof(ordenes), fp)){
        printf("%s\n",ordenes);
        token = strtok(ordenes, " ");
        tok = 0;
        while (token != NULL){
            orden[tok++] = strdup(token);
            token = strtok(NULL," ");
        }
        printf("\n%s\n",orden[0]);
        printf("\n%s\n",orden[1]);
        printf("\n%s\n",orden[2]);
        free(orden[0]);free(orden[1]);free(orden[2]);
    }
    fclose(fp);
}
#包括
#包括
#包括
int main(int argc,char*argv[]){
半焦烯[150];
char*orden[3];
字符*令牌;
int tok;
文件*fp;
fp=fopen(argv[1],“r”);
如果(fp==NULL){
printf(“文件错误”);
出口(1);
}
while(fgets(ordenes,sizeof(ordenes,fp)){
printf(“%s\n”,ordenes);
令牌=strtok(ordenes,“”);
tok=0;
while(令牌!=NULL){
orden[tok++]=strdup(令牌);
令牌=strtok(空,“”);
}
printf(“\n%s\n”,orden[0]);
printf(“\n%s\n”,orden[1]);
printf(“\n%s\n”,orden[2]);
自由(奥登[0]);自由(奥登[1]);自由(奥登[2]);
}
fclose(fp);
}

您可以执行以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void play_with_token(char *token, char const *delim)
{
  if (token == NULL)
    return;
  printf(" %s", token);
  play_with_token(strtok(NULL, delim), delim);
}

int main(int argc, char *argv[])
{
    if (argc != 2)
      return 1;
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL)
      return 1;

    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    while ((read = getline(&line, &len, fp)) != -1) {
      printf("parsing line :");
      char const *delim = " ";
      play_with_token(strtok(line, delim), delim);
      printf("\n");
    }
   free(line);
   fclose(fp);
}
#包括
#包括
#包括
使用令牌(char*token,char const*delim)进行静态无效播放
{
if(标记==NULL)
回来
printf(“%s”,标记);
使用令牌(strtok(NULL,delim),delim)播放;
}
int main(int argc,char*argv[])
{
如果(argc!=2)
返回1;
文件*fp=fopen(argv[1],“r”);
如果(fp==NULL)
返回1;
char*line=NULL;
尺寸长度=0;
阅读;
while((read=getline(&line,&len,fp))!=-1){
printf(“解析行:”);
char const*delim=“”;
使用令牌(strtok(line,delim),delim)播放;
printf(“\n”);
}
自由线;
fclose(fp);
}

您可以执行以下操作:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void play_with_token(char *token, char const *delim)
{
  if (token == NULL)
    return;
  printf(" %s", token);
  play_with_token(strtok(NULL, delim), delim);
}

int main(int argc, char *argv[])
{
    if (argc != 2)
      return 1;
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL)
      return 1;

    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    while ((read = getline(&line, &len, fp)) != -1) {
      printf("parsing line :");
      char const *delim = " ";
      play_with_token(strtok(line, delim), delim);
      printf("\n");
    }
   free(line);
   fclose(fp);
}
#包括
#包括
#包括
使用令牌(char*token,char const*delim)进行静态无效播放
{
if(标记==NULL)
回来
printf(“%s”,标记);
使用令牌(strtok(NULL,delim),delim)播放;
}
int main(int argc,char*argv[])
{
如果(argc!=2)
返回1;
文件*fp=fopen(argv[1],“r”);
如果(fp==NULL)
返回1;
char*line=NULL;
尺寸长度=0;
阅读;
while((read=getline(&line,&len,fp))!=-1){
printf(“解析行:”);
char const*delim=“”;
使用令牌(strtok(line,delim),delim)播放;
printf(“\n”);
}
自由线;
fclose(fp);
}

您的代码中存在多个问题:

  • 由于alinsoar被诊断为眼睛锐利,您不包括
    <代码>strtok未定义,编译器必须假设它返回一个
    int
    ,而它没有返回,并且该
    int
    被静默转换为
    char*
    。生成的代码调用未定义的行为,很可能会在64位目标上崩溃。您应该在编译时启用所有警告,以使编译器帮助避免此类愚蠢的错误<代码>gcc-Wall-W或
    叮当声-Weverything

  • 在调用
    fp=fopen(argv[1],“r”)之前,不检查是否已将命令行参数传递给程序。如果未传递任何参数,
    argv[1]
    是空指针

  • 当(feof(fp)==0)不正确时,读取。您应该改为编写
    while(fgets(ordenes,sizeof(ordenes),fp)){…

  • 在将
    token
    存储到
    orden
    数组中之前,不检查
    tok<3
    是否正确。如果该行有3个以上的字段,则会导致缓冲区溢出

  • 在打印
    orden
    中的所有3个条目之前,您不会检查是否确实找到了3个标记。这也可能会调用未定义的行为,尤其是当
    fgets()
    无法读取您未检查的行时

以下是一个改进的版本:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char ordenes[150];
    char *orden[3];
    char *token;
    int i, tok;

    if (argc < 2) {
        fprintf(stderr, "Missing command line argument\n");
        exit(1);
    }
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "Cannot open input file %s: %s\n", 
                argv[1], strerror(errno));
        exit(1);
    }

    while (fgets(ordenes, sizeof(ordenes), fp)) {
        printf("%s", ordenes);
        token = strtok(ordenes, " ");
        for (tok = 0; tok < 3 && token != NULL; tok++) {
            orden[tok] = strdup(token);
            token = strtok(NULL, " ");
        }
        for (i = 0; i < tok; i++) {
            printf("%s\n", orden[i]);
            free(orden[i]);
        }
        printf("\n");
    }
    fclose(fp);
    return 0;
}
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
半焦烯[150];
char*orden[3];
字符*令牌;
int i,tok;
如果(argc<2){
fprintf(stderr,“缺少命令行参数”);
出口(1);
}
文件*fp=fopen(argv[1],“r”);
如果(fp==NULL){
fprintf(stderr,“无法打开输入文件%s:%s\n”,
argv[1],strerror(errno));
出口(1);
}
while(fgets(ordenes,sizeof(ordenes,fp)){
printf(“
  for ( int i = 0; i < tok; i++ )
  {
      printf("\n%s\n", orden[i]);
      free( orden[i]);
  }
token = strtok(ordenes, " ");
token = (int->char*) strtok(ordenes, " ");