程序可以处理字符串字面值,但不能处理字符串数组



我有一个散列表ADT,它有两个函数,插入和查找。我在insert函数中放入一个哈希表、哈希表大小、ID #和书名,并将其插入哈希表中。当我传递它一个字符串字面量,即insert(...,"Hello, world!"...);时,它不起作用,当我从文件中读取字符串,将它们存储在数组中,并尝试使用我的插入和查找函数。这里有我所有的代码,但最重要的文件是main.c和hash.c。hash .c有newHash()、hash()、insert()和lookup()函数,main.c从两个文件中读取,在本例中是test1.lib。In和test1.req。在第一个文件中,将从每行获取图书馆id和书名,然后将其放入哈希表中。从第二个文件中,它获得对书名的请求,并应该在其链表中打印id。

  • 文件链接列表 https://docs.google.com/document/d/1tFNs-eVkfnCfjwAHcAUdHtUl1KVv_WcnW2IS0SRFvcM/edit?usp=sharing

工作的代码示例。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "list.h"
#include "hash.h"
int main(){
    ListHndl* temp = newHash(10);
    insert(442440, "cvyaqbznxel", 10,temp);
    lookup(temp,"cvyaqbznxel", 10);
    return 0;
}

不工作的代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "list.h"
#include "hash.h"

int main(int argc, char * argv[]) {
    if (argc != 3) {
        printf("Incorrect arguments, please specify 2 files to be readn");
        return EXIT_FAILURE;
    }
    FILE *file = fopen( argv[1], "r");
    FILE *secondFile = fopen(argv[2], "r");
    if (file == 0 || secondFile == 0) {
        printf("Could not open a filen");
        return EXIT_FAILURE;
    }
    int numDataLines2;
    int numDataLines;
    int hashTableSize;
    //First line of first file gives number of lines in file and 
    //size of hash table to be made
    if(fscanf(file, "%d%d", &numDataLines, &hashTableSize) < 2) {
        printf("Unable to parse first line of first filen");
        return EXIT_FAILURE;
    } 
    ListHndl* theHash = newHash(hashTableSize);
    int libraryID;
    char *tempString = calloc(numDataLines,41*sizeof(char));
    char lineHolder[129];
    //discard the new line which always shows up
    fgets(lineHolder, 128, file);
    for(int i = 0; i < numDataLines; i++) {
        //Gets the whole line to be scanned with sscanf
        fgets(lineHolder, 128, file);
        //If the line consists of just a newline char, continue
        if(strcmp(lineHolder, "n") == 0 ) {
            continue;
        }
        //Scans the line retrieved from fgets and placed in lineHolder
        if(sscanf(lineHolder, "%d, %40[^n]", &libraryID,&tempString[i]) == 0){
            printf("Unable to parse line %d of first filen",i+2);
            return EXIT_FAILURE;
        }
        insert(libraryID, &tempString[i], hashTableSize, theHash);
    }
    char String[41];
    fgets(String, 40, secondFile);
    numDataLines2 = atoi(String);
    char *storeSecondFileStuff = calloc(numDataLines2,41*sizeof(char));
    for(int i = 0; i< numDataLines2; i++) {
        fgets(lineHolder, 128, secondFile);
        if(strcmp(lineHolder, "n") == 0) {
            continue;
        }
        if(sscanf(lineHolder, "%40[^n]",&storeSecondFileStuff[i]) == 0) {
            printf("Unable to parse line %d of second filen",i+2);
            return EXIT_FAILURE;
        }
        lookup(theHash, &storeSecondFileStuff[i], hashTableSize);
    }
    printf("n");
    fclose(file);
    fclose(secondFile);
    return 0;
}

谢谢!

我想你有很多问题。首先,您可能没有正确扫描输入行。修改行

 if(sscanf(lineHolder, "%d, %40[^n]", &libraryID,&tempString[i]) == 0)

 if(sscanf(lineHolder, "%d, %40[^n]", &libraryID, tempString) < 0)

这样,您将捕获sscanf函数没有成功转换两个参数的情况—例如,如果输入行中没有逗号。注意,sscanf返回成功转换的次数;成功将返回2的值,因此测试<2是正确的方法。

还注意我将&tempString[i]更改为tempString。前者指向tempString上的某个位置——它只分配了41个字符。然而,您总是允许最多40个字符(加上'')写入它-因此您将写入超过字符串的末尾。因为这只是一个临时变量,所以这样做没有意义。只需将输入扫描到temp变量中,然后对它做任何您需要做的事情。

这意味着你的insert也改变了,从

    insert(libraryID, &tempString[i], hashTableSize, theHash);

    insert(libraryID, tempString, hashTableSize, theHash);

同样,您需要在代码的下面做同样的事情。

这是一个让代码为你工作的尝试-看看这是否击中了点。注意,我所做的只是更改了tempStringstoreSecondFileStuff的类型,并相应地修改了它们在各种函数调用中的使用方式。我没有尝试编译/运行,因为涉及到其他文件的复杂性-但这应该有所帮助:

int main(int argc, char * argv[]) {
    if (argc != 3) {
        printf("Incorrect arguments, please specify 2 files to be readn");
        return EXIT_FAILURE;
    }
    FILE *file = fopen( argv[1], "r");
    FILE *secondFile = fopen(argv[2], "r");
    if (file == 0 || secondFile == 0) {
        printf("Could not open a filen");
        return EXIT_FAILURE;
    }
    int numDataLines2;
    int numDataLines;
    int hashTableSize;
    //First line of first file gives number of lines in file and 
    //size of hash table to be made
    if(fscanf(file, "%d%d", &numDataLines, &hashTableSize) < 2) {
        printf("Unable to parse first line of first filen");
        return EXIT_FAILURE;
    } 
    ListHndl* theHash = newHash(hashTableSize);
    int libraryID;
    char **tempString = calloc(numDataLines,sizeof(char*));  // <<< ARRAY of pointers
    char lineHolder[129];
    //discard the new line which always shows up
    fgets(lineHolder, 128, file);
    for(int i = 0; i < numDataLines; i++) {
        //Gets the whole line to be scanned with sscanf
        fgets(lineHolder, 128, file);
        tempString[i] = calloc(1, 41 * sizeof(char)); // <<< space for this string
        //If the line consists of just a newline char, continue
        if(strcmp(lineHolder, "n") == 0 ) {
            continue;
        }
        //Scans the line retrieved from fgets and placed in lineHolder
        if(sscanf(lineHolder, "%d, %40[^n]", &libraryID, tempString[i]) < 0){ // <<< changed
            printf("Unable to parse line %d of first filen",i+2);
            return EXIT_FAILURE;
        }
        insert(libraryID, tempString[i], hashTableSize, theHash); // <<< changed
    }
    char String[41];
    fgets(String, 40, secondFile);
    numDataLines2 = atoi(String);
    char **storeSecondFileStuff = calloc(numDataLines2, sizeof(char*)); // changed: again char **
    for(int i = 0; i< numDataLines2; i++) {
        fgets(lineHolder, 128, secondFile);
        storeSecondFileStuff[i] = calloc(1, 41 * sizeof(char));
        if(strcmp(lineHolder, "n") == 0) {
            continue;
        }
        if(sscanf(lineHolder, "%40[^n]",storeSecondFileStuff[i]) == 0) {
            printf("Unable to parse line %d of second filen",i+2);
            return EXIT_FAILURE;
        }
        lookup(theHash, storeSecondFileStuff[i], hashTableSize); // <<<< changed
    }
    printf("n");
    fclose(file);
    fclose(secondFile);
    return 0;
}

最新更新