【问题标题】:Having problems with scanf if a word is bigger than 7 characters如果单词大于 7 个字符,scanf 会出现问题
【发布时间】:2016-08-08 18:45:48
【问题描述】:

我正在从控制台读取一些单词,将它们放在一个列表中,然后打印出来。出于某种原因,如果我输入类似

qwertyu qwertyu

它打印 “第一个词:qwertyu //第二个词:qwertyu”
但是如果我输入

qwertyui qwertyui

它打印“第一个词:qwertyuiqwertyui //第二个词:qwertyui”
任何超过 7 个字符的单词都会导致它克隆自己,我不知道为什么会这样。

这是我的一些代码:

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

int total_pal = 2000; //Total de palavras
int nelem = 0; //Numero de elementos da lista LISTA
int numero = 0; //Numero de elementos da lista FIM

typedef struct Palavra{ //Criando uma estrutura pra palavra
    char *caracs; //Consiste de caracteres
    int freq; //e sua freqência

}Palavra;

Palavra *lista; //Lista de palavras
Palavra *fim; //Lista de palavras depois do parse
Palavra *temp; //Lista temporaria para fazer ondernação

/*struct Palavra *newPalavra(char *caracs, int freq){
    struct Palavra *palavra = malloc(sizeof(struct Palavra)); //Alocando memoria pra palavra
    if (palavra == NULL)
        printf("Deu erro no malloc de palavra!");

    palavra->caracs = malloc (sizeof(char)); //Alocando memoria pros caracteres da palavra
    if(palavra->caracs == NULL){
        free(palavra);
        printf("Deu erro no malloc de caracter!");
    }

    palavra->caracs = strdup(caracs); //Define os caracteres dentro da estrutura como o char passado na chamada
    palavra->freq = freq; //Mesma coisa com a frequencia
    return palavra;
}*/

int busca(Palavra *fim, char *palavra){ //Busca palavra na lista
    int l = 0;
    while(l<numero && strcmp(fim[l].caracs, palavra) != 0){ //Equanto i for menor do que o numero total de palavras existentes e a palavra na lista for diferente da palavra procurada
        l++; //Vai somando até achar ou não a palavra
    }
return l; //retorna posição
}

void troca(Palavra *lista, int i, int j){ //Usada na ordenação
    *temp = lista[i];
    lista[i] = lista[j];
    lista[j] = *temp;
}

void ordena(Palavra *fim,int nelem){ //Ordena a lista fim em ordem decrescente de frequência
    for(int i = 0;i<(nelem-1);i++){
        for(int j = (i+1);j<nelem;j++){
            if (fim[i].freq<fim[j].freq){
                troca(fim,i,j);
            }
        }
    }
}

void alfabetica(Palavra *lista,int nelem){
    for (int i = 1; i < nelem; i++) {
      for (int j = 1; j < nelem; j++) {
         if (strcmp(&lista[j-1].caracs, &lista[j].caracs) > 0) {
            troca(lista,j,j-1);
         }
      }
   }
}

int main(){
    lista= malloc(sizeof(struct Palavra)*total_pal); //Aloca memoria pra lista usada pro scanf
    if (lista == NULL)
        printf("Deu erro!");

    temp= malloc(sizeof(struct Palavra)); //Aloca memoria pra lista temporaria usada na ordenação
    if (lista == NULL)
        printf("Deu erro!");

    fim= malloc(sizeof(struct Palavra)*total_pal); //Aloca memoria pra lista final
    if (fim == NULL)
        printf("Deu erro!");

    while(scanf("%s",&lista[nelem].caracs)!= EOF){ //Le input do console até chegar um EOF e adiciona tudo na lista
        nelem++;
    }

    alfabetica(lista,nelem); //Ordena a lista em ordem alfabetica

    for(int p=0;p<nelem;p++){ //Imprime as palavras junto com suas frequências
        printf("Palavra: %s\n",&lista[p].caracs);
    }

    for(int k = 0;k<nelem;k++){
        int pos = busca(fim,&lista[k].caracs);

        if(pos != numero){ //Palavra já consta
            fim[pos].freq++; //Incrementa a frequência dela

        }
        else if (numero == total_pal){
            printf("overflow!");
        }
        else if(pos == numero){ //Palavra não consta
            fim[pos].caracs = &lista[k].caracs; //Define a palavra na posição correta na lista fim como o pch
            fim[pos].freq = 1; //Define sua frequencia como 1
            numero++;
            //printf("adicionei\n");
        }
   }

    ordena(fim,numero); //Ordena a lista fim por frequencia

    for(int p=0;p<numero;p++){ //Imprime as palavras junto com suas frequências
        printf("Palavra: %s   Frequencia: %d\n",fim[p].caracs,fim[p].freq);
    }

    free(lista); //Libera a memoria usada nas listas
    free(temp);
    free(fim);
}

【问题讨论】:

  • 什么是Palavra?你在哪里为字符串分配内存?你似乎没有在任何地方打电话给newWord?如果listaWord 结构的数组,那么表达式&amp;lista[nelem].caracs 会给你一个指向指针 caracs 的指针(即它是char ** 的类型),它是不是scanf 所期望的。一个好的编译器将能够检测到它并给你一个警告。
  • 哦,你的 newWord 函数每次调用都会有一个字节的内存泄漏。
  • 也缺少一些包含。 nelem 未定义。我仍然想知道你是如何编译这段代码的^^
  • 抱歉,Palavra 是 Word。忘记改了。你认为这个内存泄漏是什么原因造成的吗?
  • 除非您发布minimal complete and verifiable example,否则您是在浪费您的时间和我们的时间。确保您发布的内容完全按照所示编译并且能够重现问题。如前所述 - 为什么从未调用过 newWord

标签: c string char scanf


【解决方案1】:

您需要为您分配的每个结构中的 caracs 值分配内存。

 lista= malloc(sizeof(struct Palavra)*total_pal);
 int i;
 const int SIZE_STR = 100;
 for (i = 0; i < total_pal; i++) {
     lista[i].caracs = malloc(sizeof(char) * SIZE_STR);
 }

【讨论】:

    猜你喜欢
    • 2021-10-22
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-06
    • 2022-06-12
    相关资源
    最近更新 更多