2017-04-06 82 views
0

我是C新手,编写代码来帮助我进行数据分析。它的一部分打开预定的文件。strncpy fuctions生成错误的文件名

这段代码给我的问题,我不明白为什么。

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


#define MAXLOGGERS 26 

// Declare the input files 
char inputfile[]; 
char inputfile_hum[MAXLOGGERS][8]; 

// Declare the output files 
char newfile[]; 
char newfile_hum[MAXLOGGERS][8]; 

int main() 
{ 
    int n = 2; 
    while (n > MAXLOGGERS) 
    { 
     printf("n error, n must be < %d: ", MAXLOGGERS); 
     scanf("%d", &n); 
    } 

    // Initialize the input and output file names 
    strncpy(inputfile_hum[1], "Ahum.csv", 8); 
    strncpy(inputfile_hum[2], "Bhum.csv", 8); 
    strncpy(newfile_hum[1], "Ahum.txt", 8); 
    strncpy(newfile_hum[2], "Bhum.txt", 8); 


    for (int i = 1; i < n + 1; i++) 
    { 

     strncpy(inputfile, inputfile_hum[i], 8); 

     FILE* file1 = fopen(inputfile, "r"); 
     // Safety check 
     while (file1 == NULL) 
     { 
      printf("\nError: %s == NULL\n", inputfile); 
      printf("\nPress enter to exit:"); 
      getchar(); 
      return 0; 
     } 

     strncpy(newfile, newfile_hum[i], 8); 

     FILE* file2 = fopen(newfile, "w"); 
     // Safety check 
     if (file2 == NULL) 
     { 
      printf("Error: file2 == NULL\n"); 
      getchar(); 
      return 0; 
     } 

     for (int c = fgetc(file1); c != EOF; c = fgetc(file1)) 
     { 
      fprintf(file2, "%c", c); 
     } 

     fclose(file1); 
     fclose(file2); 
    } 
// system("Ahum.txt"); 
// system("Bhum.txt"); 
} 

此代码生成两个文件,但不是名称:

Ahum.txt 
Bhum.txt 

的文件被命名为:

Ahum.txtv 
Bhum.txtv 

的原因,我在for循环,因为N使用strncpy实际上将在稍后由用户输入。

谢谢你的时间!

+0

您需要9个空格内存来存储8个字符,因为需要额外的\ 0终止c字符串 –

回答

1

我在这里看到至少三个问题。

第一个问题是你的字符数组对于你的字符串来说太小了。 “ahum.txt”等将需要9个字符。八为实际文本再加一个为空终止字符。

第二个问题是您已经将字符数组“newfile”和“inputfile”声明为空数组。这些也需要是一个能够包含字符串的数字(至少9)。 幸运的是,没有将程序空间中的内存覆盖掉。

第三个也是最后一个问题是你使用strcpy()。 strncpy(dest,src,n)会将n个字符从src复制到dest,但如果n等于或小于src字符串的大小,它不会复制最终的null结束符字符。

从函数strncpy()手册页:https://linux.die.net/man/3/strncpy

的函数strncpy()函数...最多n SRC的字节被复制。 警告:如果src的前n个字节中没有空字节,则 放置在dest中的字符串将不会以null结尾。

通常情况下,您想要做的是将目标缓冲区的大小减1以允许空字符。

例如: strncpy(dest,src,sizeof(dest) - 1); //假设dest是字符数组

+0

Thanx,现在它的工作! 但我宣布大小为8的字符数组的原因是因为我也计算了0。实际上不是inputfile_hum [MAXLOGGERS] [8]有9个字符的空间吗? [0]: “A”, [1]: “H”, [2]: “U”, [3]: “m” 个, [4]: “”, [5] :“t”, [6]:“x”, [7]:“t”, [8]:“\ n” –

+0

很好用。数组大小是实际大小,而不是最高索引的值。一个8的数组的索引从0到7.请注意是否有帮助 – MrJLP

+0

不幸的是,upvoting需要15个声望! –

0

您的代码有几个问题。

  1. inputfile_hum,newfile_hum需要是字符串尾随'\ 0'大一个字符。

    char inputfile_hum [MAXLOGGERS] [9]; ... char newfile_hum [MAXLOGGERS] [9];

  2. strncpy()函数预期的第一个参数是一个char *区域大到足以容纳预期的结果,所以inputfile中[]和OUTPUTFILE []需要声明:

    焦炭inputfile中[9]。 char outputfile [9];