【问题标题】:length of a string with scanf("%number[^\n], array[N].struct)scanf("%number[^\n], array[N].struct) 的字符串长度
【发布时间】:2014-12-04 11:49:21
【问题描述】:

所以,我必须创建一个程序来管理库而不使用#include

我的问题是在我用来添加一本书的函数中,我必须告诉用户他是否超出了数组限制。你建议我怎么做?

我决定使用scanf(" %NUMBER[^\n], libro[i].title)

这是我到目前为止所拥有的(在 printf 中,我基本上要求输入作者和内容,或者我告诉用户他超出了限制):

int main(int argc, char *argv[]){
    int N, codice, i = 0, j = 0;
    book Library[MAXlibri];
    boolean ricerca, esito;

void InsertBook(book libro[], int i){
    printf("Inserire il titolo del libro (max 50 caratteri)\n");
    scanf(" %49[^\n]", libro[i].title);
    if(sizeof(libro[i].title) > 50){
        printf("Sono stati inseriti troppi caratteri quando si inseriva il titolo del libro\n");
    }
    printf("Inserire autore o autori (max 30 caratteri)\n");
    scanf(" %29[^\n]", libro[i].auth);
    if(sizeof(libro[i].auth) > 30){
        printf("Sono stati inseriti troppi caratteri quando si inseriva l'autore\n");
    }
    printf("Inserire casa editrice (max 20 caratteri)\n");
    scanf(" %19[^\n]", libro[i].editor);
    if(sizeof(libro[i].editor) > 20){
        printf("Sono stati inseriti troppi caratteri quando si inseriva la casa editrice\n");
    }
    printf("Inserire una breve descrizione (max 50 caratteri)\n");
    scanf(" %49[^\n]", libro[i].descr);
    if(sizeof(libro[i].descr) > 50){
        printf("Sono stati inseriti troppi caratteri quando si inseriva la descrizione\n");
    }
    printf("Inserire genere letterario (max 20 caratteri)\n");
    scanf(" %19[^\n]", libro[i].genre);
    if(sizeof(libro[i].genre) > 20){
        printf("Sono stati inseriti troppi caratteri quando si inseriva il genere letterario\n");
    }
    printf("Inserire codice numerico libro\n");
    scanf("%d", &libro[i].code);
    printf("Inserire anno di pubblicazione\n");
    scanf("%d", &libro[i].year);
    printf("Inserire numero pagine\n");
    scanf("%d", &libro[i].pages);
    if(sizeof(libro[i].title) < 50 && sizeof(libro[i].auth) < 30 && sizeof(libro[i].editor) < 20 && sizeof(libro[i].descr)<50 && sizeof(libro[i].genre) < 20){
        printf("Libro inserito con successo!\n");
    }
    else{
        printf("Il libro non e' stato inserito correttamente, riprovare\n");
    }
}

【问题讨论】:

  • 你是什么意思“没有#include?如果不包含stdio.h,您就不能使用scanf,而且您的格式可能是错误的:" %19[^\n]" 读取19 到底是什么?我认为你想要" %19[^\n]s"
  • @EliasVanOotegem " %19[^\n]s" : s 不是必需的。
  • @BLUEPIXY:没错,你是……不过,没有#include 位很奇怪。 OP 可能在没有意识到的情况下依赖 gcc 的自动包含。 -Wall -pedantic 标志可能没有在这里使用
  • @EliasVanOotegem 是的,只是在#include 之外添加了一个原型。它可能无法作为一个整体发挥作用。

标签: c arrays string scanf sizeof


【解决方案1】:

我认为这里有几个问题: 首先,也是最重要的一点,您可能需要重新考虑如何管理图书馆中书籍的内存。允许标题、作者等的最大字符数是一个非常糟糕的主意。你会遇到严重的限制。

为此,我建议您使用字符串,因为内存分配是透明的,这会使事情变得更容易一些 - 您可以调整大小、清除、删除它们而不必过多担心内存。 如果您坚持使用字节数组(即 char[N]),您可以这样做,但您应该动态分配内存。这将允许您的字段具有任意长度,并且不会浪费内存。

通过查看核心,我怀疑您使用的是静态分配的缓冲区。我真的希望你没有将它们分配到堆栈上,因为那对它们来说是最糟糕的地方。如果您坚持静态分配它们,则应在全局范围内声明它们,因此至少要在 .data 部分中进行

回到你最初的问题,如何获得长度,你可以使用 scanf("%s\n"),然后使用 strlen。

要读取字符串,您可以使用任何您想要的函数,只要您考虑到限制:fgets 在 '\n' 或 EOF 处停止。例如,如果您有两行标题,这可能是一个问题)。另一方面,scanf 读取格式化的文本,所以你必须小心你的文本都是以相同的方式格式化的。

希望对你有帮助

【讨论】:

    【解决方案2】:

    示例测试代码。

    #include <stdio.h>
    #include <string.h>
    
    int main (){
        char buff[10+1];
        char ch = 0;
        int len;
        while(1){
            printf("input max 10 characer(type '.' for exit)\n");
            scanf(" %10[^\n]%c", buff, &ch);
            if(*buff == '.')
                break;
            len = strlen(buff);
            printf("i received : '%s'\n", buff);
            printf("input length : %d\n", len);
            if(ch != '\n'){//Input is greater than in the case where a newline is not set
                printf("you typed greater than 10 character\n");
                while(getchar() != '\n')
                    ;//drop upto newline
            }
        }
        return 0;
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-22
      • 1970-01-01
      • 2011-05-11
      • 1970-01-01
      • 2013-02-28
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      相关资源
      最近更新 更多