Home > front end >  C: Fill array only with the size of scanfed string
C: Fill array only with the size of scanfed string

Time:12-25

After i put a name in the terminal and it is shorter, then 20 chars, it wants inputs until i have filled all the 20 positions in the array. I know it is because of the for cycle i have there, but I don't know how else to fill that end of the array with nothing(""). In the array there is for example this "Helloworld\n123\n123" Thank you for help in advance.

#define NAME 20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
main(void) {
    char name[NAME] = {""};
    malloc(sizeof(name[NAME]));

    printf("Choose your name: ");
    for (int i = 0; i < NAME; i  ) {
        scanf("%c", &name[i]);
    }

    //Welcome and the name
    printf("Welcome: "); 
    for (int i = 0; i < NAME; i  ) {
        printf("%c", name[i]);
    }
    return 0;
}

CodePudding user response:

You need to stop reading at a newline ( should also check return codes).

A loop like:

    size_t i=0;
    for (; i < sizeof(name)-1; i  ) {
        if (1==(scanf("%c",&name[i]))){ if (name[i]=='\n') break; }
        else if (feof(stdin)) break; //end of file?
        else return perror("getchar"),1; //report error
    }
    name[i]='\0';

will achieve that (can also use getchar/getc/fgetc instead of scanf) or you can use fgets:

    if(NULL==fgets(name,sizeof(name),stdin)) return perror("fgets"),1;
    //erase a possibly included newline at the end
    //(won't be there if you pressed Ctrl D twice rather than
    //Enter to submit your input or if you're at the end of 
    //a stdin redirected from a file)
    size_t len = strlen(name);
    if(name[len-1]=='\n') name[len-1]='\0';

Whole program with both versions (in the if(0){...}else{...}) :

#define NAME 20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
 
int main(void) {
    char name[NAME] = {""};
    //malloc(sizeof(name[NAME])); //a useless memory leak; don't do this!

    printf("Choose your name: ");
    if(0){
        if(NULL==fgets(name,sizeof(name),stdin)) return perror("fgets"),1;
        size_t len = strlen(name);
        if(name[len-1]=='\n') name[len-1]='\0';
    }else{
        size_t i=0;
        for (; i < sizeof(name)-1; i  ) {
            if (1==(scanf("%c",&name[i]))){ if (name[i]=='\n') break; }
            else if (feof(stdin)) break; //end of file?
            else return perror("getchar"),1;
        }
        name[i]='\0';
    }

    //Welcome and the name
    printf("Welcome: ");
    for (int i = 0; i < NAME; i  ) {
        printf("%c", name[i]);
    }
    return 0;
}

CodePudding user response:

If you have to use scanf and %c format:

char *readLineUsingCharAndScanf(char *buff, size_t size, FILE *fi)
{
    char ch;
    char *wrk = buff;
    while(size-- && fscanf(fi, "%c", &ch) == 1 && ch != '\n' ) *wrk   = ch;
    *wrk = 0;
    return buff;
}

void dumpString(const char *restrict str, size_t size)
{
    while(*str && size--)
    {
        printf("d [0xx] - %s\n", *str, *str, (*str >= 32 & *str <= 127) ? (char[]){'\'', *str, '\'', 0} : "not printable");
        str  ;
    }
}

int main(void)
{
    char name[20];

    dumpString(readLineUsingCharAndScanf(name, 19, stdin), 20);
}

https://godbolt.org/z/vWvP68TbW

CodePudding user response:

Thank you everyone for answering. Unfortunately the first two answers are too complicated for me yet. And the third one was not working properly.

But I found the simplest answer. :) Many thanks

#include <stdio.h> 
int main(void) 
{ 
    char name[20]; 
    printf("Choose your name: "); 
    scanf("%[^\n]*c",name); 
     
    printf("My name is %s",name); 
     
} 

CodePudding user response:

scanf() is not the best tool for your purpose. Here is a simple and safe solution:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
#define NAME 20

int main(void) {
    char name[NAME];
    int c;
    size_t i;

    printf("Enter your name: ");
    i = 0;
    while ((c = getchar()) != EOF && c != '\n') {
        if (i < sizeof(name) - 1)
            name[i  ] = c;
    }
    name[i] = '\0';

    //Welcome and the name
    printf("Welcome: %s\n", name); 

    return 0;
}

If you must use scanf(), use this:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
 
#define NAME 20

int main(void) {
    char name[NAME];
    char c;
    size_t i;

    printf("Enter your name: ");
    i = 0;
    while (scanf("%c", &c) == 1 && c != '\n') {
        if (i < sizeof(name) - 1)
            name[i  ] = c;
    }
    name[i] = '\0';

    //Welcome and the name
    printf("Welcome: %s\n", name); 

    return 0;
}

CodePudding user response:

For your needs I would use scanf with the string conversion specifier %s. In this case, the input name would be read and stored character by character in the buffer until the whitespace would be read. Here is the code.

#define NAME 20
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char name[NAME] = {""};
    malloc(sizeof(name[NAME]));
    printf("Choose your name: ");
    scanf("%s", &name);
    printf("%s", &name);

    return 0;
}
  •  Tags:  
  • c
  • Related