C Printf()按顺序打印字符串参数

C Printf()按顺序打印字符串参数,c,printf,C,Printf,我有一些C代码,它逐行读取文本文件,对每行中的字符串进行散列,并保持具有最大散列值的字符串的运行计数 它似乎在做正确的事情,但当我发布打印声明时: printf("Found Bigger Hash:%s\tSize:%d\n", textFile.biggestHash, textFile.maxASCIIHash); “我的打印”将在输出中返回: 预处理:dict1 发现大小:110h:a 发现大小:857h:aardvark 发现BiSize:861h:aardwolf 发现的

我有一些C代码,它逐行读取文本文件,对每行中的字符串进行散列,并保持具有最大散列值的字符串的运行计数

它似乎在做正确的事情,但当我发布打印声明时:

 printf("Found Bigger Hash:%s\tSize:%d\n", textFile.biggestHash, textFile.maxASCIIHash);    
“我的打印”将在输出中返回:

预处理:dict1
发现大小:110h:a
发现大小:857h:aardvark
发现BiSize:861h:aardwolf
发现的BiSize:937h:已放弃
找到的BiSize:951h:放弃者
发现BiSize:1172:放弃
已找到BiSize:1283:缩写
发现BiSize:1364:无机成因
发现BiSize:1593:非生物成因
发现BiSize:1716:心不在焉
发现二等分:1726:棘翅目
发现BiSize:1826:适应性
发现于1932年:腺癌
发现:2162:促肾上腺皮质激素
发现BiSize:2173:化学自养
发现BiSize:2224:反革命
发现:2228:反革命者
发现BiSize:2258:树状年代学
发现:2440:脑电图
发现大小:4893:肺炎显微镜硅溶胶尘肺
最大尺寸:46um结果合计字:71885卵锥虫病

看来我误用了printf()。代码如下:

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

#define WORD_LENGTH 100 // Max number of characters per word

// data1 struct carries information about the dictionary file; preprocess() initializes it
struct data1
{
   int numRows; 
   int maxWordSize; 
   char* biggestWord;
   int maxASCIIHash; 
   char* biggestHash;  
}; 

int asciiHash(char* wordToHash); 
struct data1 preprocess(char* fileName); 


int main(int argc, char* argv[]){

   //Diagnostics Purposes; Not used for algorithm  
   printf("Preprocessing: %s\n",argv[1]); 
   struct data1 file = preprocess(argv[1]); 
   printf("Biggest Word:%s\t Size:%d\tTotal Words:%d\n", file.biggestWord, file.maxWordSize, file.numRows);  
   //printf("Biggest hashed word (by ASCII sum):%s\tSize: %d\n", file.biggestHash, file.maxASCIIHash);  
   //printf("**%s**", file.biggestHash); 
   return 0; 
}

int asciiHash(char* word)
{
   int runningSum = 0; 
   int i;
   for(i=0; i<strlen(word); i++)
   {
      runningSum += *(word+i); 
   }
   return runningSum; 
}

struct data1 preprocess(char* fName)
{
   static struct data1 textFile = {.numRows = 0, .maxWordSize = 0, .maxASCIIHash = 0};
   textFile.biggestWord = (char*) malloc(WORD_LENGTH*sizeof(char));    
   textFile.biggestHash = (char*) malloc(WORD_LENGTH*sizeof(char));  
   char* str = (char*) malloc(WORD_LENGTH*sizeof(char)); 

   FILE* fp = fopen(fName, "r"); 
   while( strtok(fgets(str, WORD_LENGTH, fp), "\n") != NULL)
   {
      // If found a larger hash
      int hashed = asciiHash(str);
      if(hashed > textFile.maxASCIIHash)
      { 
         textFile.maxASCIIHash = hashed;  // Update max hash size found
         strcpy(textFile.biggestHash, str); // Update biggest hash string
         printf("Found Bigger Hash:%s\tSize:%d\n", textFile.biggestHash, textFile.maxASCIIHash);   
      }
      // If found a larger word
      if( strlen(str) > textFile.maxWordSize)
      {
         textFile.maxWordSize = strlen(str); // Update biggest word size
         strcpy(textFile.biggestWord, str); // Update biggest word 
      }
      textFile.numRows++; 
   }

   fclose(fp); 
   free(str); 
   return textFile; 
}
#包括
#包括
#包括
#定义单词长度100//每个单词的最大字符数
//data1结构携带有关字典文件的信息;preprocess()初始化它
结构数据1
{
int numRows;
int-maxWordSize;
字符*最大的单词;
int-maxasihash;
char*biggestHash;
}; 
int asciiHash(char*wordToHash);
结构数据1预处理(字符*文件名);
int main(int argc,char*argv[]){
//诊断目的;不用于算法
printf(“预处理:%s\n”,argv[1]);
结构数据1文件=预处理(argv[1]);
printf(“最大单词:%s\t大小:%d\t总单词:%d\n”,file.biggestWord,file.maxWordSize,file.numRows);
//printf(“最大散列字(按ASCII和):%s\t大小:%d\n”,file.biggestHash,file.maxasihash);
//printf(“***%s**”,file.biggestHash);
返回0;
}
int asciiHash(字符*字)
{
int runningSum=0;
int i;
对于(i=0;i textFile.maxasihash)
{ 
textFile.maxasihash=hashed;//找到更新最大哈希大小
strcpy(textFile.biggestHash,str);//更新最大的哈希字符串
printf(“找到更大的散列:%s\t大小:%d\n”,textFile.biggestHash,textFile.maxasihash);
}
//如果找到一个更大的词
if(strlen(str)>textFile.maxWordSize)
{
textFile.maxWordSize=strlen(str);//更新最大字号
strcpy(textFile.biggestWord,str);//更新最大的单词
}
textFile.numRows++;
}
fclose(fp);
自由基(str);
返回文本文件;
}
您的声明

while( strtok(fgets(str, WORD_LENGTH, fp), "\n") != NULL)
不考虑来自
fgets()
的返回值或
strtok()
的工作方式

这样做的方法是

char *fptr, *sptr;
while ((fptr = fgets(str, WORD_LENGTH, fp)) != NULL) {
    sptr = strtok(fptr, "\n");
    while (sptr != NULL) {
        printf ("%s,", sptr);
        sptr = strtok (NULL, "\n");
    }
    printf("\n");
}

注意:与第一次调用
strtok()
后相比,对同一序列的后续调用必须传递参数
NULL

读取后忘记删除
\r
。这是因为(1)您的源文件来自Windows计算机(或至少来自使用
\r\n
行结尾的计算机),以及(2)您使用
fopen
模式
“r”
,该模式不会在操作系统上翻译行结尾(同样,可能是Windows)

这将产生如下奇怪的输出:

找到更大的哈希值:text\r\t大小:123
–请参见
\r
的位置?那么,当输出这个字符串时会发生什么呢

Found Bigger Hash:text
然后通过
\r
将光标重新定位到行的开头。接下来,将输出一个选项卡–不是通过打印空格,而是仅将光标移动到第8个位置:

1234567↓
Found Bigger Hash:text
字符串的其余部分打印在已显示的字符串上:

Found BiSize:123h:text
可能的解决办法:

  • “rt”
    “文本”模式下打开文件,和/或
  • 检查并删除
    \r
    代码以及
    \n
  • 两者我都愿意
    strchr
    非常便宜,可以让您的代码更简单


    (另外,请将您的
    fgets
    行拆分为几个不同的操作来简化它。)

    问题可能出在字符串中,而不是printf。例如,回车(
    '\r'
    )可能会弄乱文本显示。将输出重定向到文件,并使用十六进制编辑器检查是否有奇怪的字符。请阅读并回复。你说得对,melpomene!Jongware,我从来没有这样调试过。您是否使用重定向操作符?谢谢您的回复。输入文件实际上由许多行组成,在这些行上会出现一个单词和一个换行符(或者我认为是这样),因此不需要多次调用strtok(NULL)。因此,我认为嵌套strtok(fgets())是可以的。我之前几乎删除了这个答案,因为很明显您使用
    strtok
    来删除行尾。第1点。使用strtok(…,“\r\n”)覆盖所有类型的行尾。第2点,如果文件没有数据,并且在第一次调用时将
    NULL
    fgets()
    传递到
    strtok()
    ,会发生什么情况?我的建议是:最好独立分析函数值。如果没有要检索的令牌,strtok(NULL,“\n”)将返回NULL(如果传递strtok()NULL,则会返回NULL)。因此,如果fgets()返回NULL,这是正常的(尽管不好看)。@MinhTran否,当我在第一次调用时将
    NULL
    作为第一个参数传递给
    strtok()
    时,系统挂起,因为它的内部状态尚未初始化。您只能在后续调用中传递
    NULL
    ,以分析最初传递的字符串。