-2

I'm trying to practice some stuff about text files, printing and reading from them. I need to take input from user -maybe their phone number or someone else's- but i want them to be able to use spaces between numbers

Lets say my phone number is: 565 856 12 i want them to be able to give me this number with spaces, instead of a squished version like 56585612

So far i've tried scanf() and i don't know how to make scanf() do something like this. I've tried going for chars and for loops but its a tangle.

And when i type 565 856 12 and press enter, only 565 will be counted for the phone number. and 856 12 goes for the next scanf.

struct Student{
   unsigned long long student_phone_number;
}


int main(){
   FILE *filePtr;
   filePtr = fopen("std_info.txt","w");

   struct Student Student1;
   printf("\nEnter Student's Phone Number: ");
      scanf("%llu",&Student1.student_phone_number);
      fprintf(filePtr,"%llu\t",Student1.student_phone_number);

}
  • 3
    A phone number is best treated as a string, not an integer. Leading zeros don't work with integers. International prefixes (+1, +44, etc) don't work. Punctuation generally — +1 (650)916-2234 — doesn't work. – Jonathan Leffler Jan 15 '22 at 12:17
  • 2
    Don't use integers for things like telephone numbers. An Integer only hold the value of a number, not its representation. It doesn't distinguish between `0123` and `123`, and it doesn't let you store special characters like `+`. – HAL9000 Jan 15 '22 at 12:17
  • thanks, will take it as chars then. but still, spaces are a pain arent they? – user9560064 Jan 15 '22 at 12:27
  • @user9560064 Yes, embedded spaces are a pain with `scanf`. You have two choices: (1) use the rather deeply mysterious and problematic `%[…]` format, or (2) don't use `scanf` at all, switching to something like `fgets` (although then you have to worry about the trailing `\n`). – Steve Summit Jan 15 '22 at 13:12
  • 2
    Please note that questions tend to be more useful to other people if you provide a [mre] of the problem. Since your immediate problem is only about inputting from `stdin` and storing it in a `struct`, and not about outputting to a file, your question would have been a bit better if your code example would have limited itself to reading from `stdin` and writing to `stdout`. By instead opening a file for output in the posted code of your question, you made your code more complicated than necessary. This may have decreased the chance of your question being upvoted. – Andreas Wenzel Jan 15 '22 at 14:01

4 Answers4

2

To solve this problem, I modified the Student structure to store both unsigned long long integers and character array. User reads character array from stdin. The read data is validated using the isValid() method, and the string is converted to an unsigned long long integer using the convertToNumber() method.

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

struct Student{
    unsigned long long numberForm;  
    char *textForm;             
};

// Converts character array to unsigned long long integer.
void convertToNumber(struct Student * const student);
// Validates the data in the Student.textForm variable.
bool isValid(const char * const input, const char * const format);
// Returns the number of characters in a character array.
size_t getSize(const char * const input);
// This function returns the "base ^ exponent" result.
unsigned long long power(int base, unsigned int exponent);

int main()
{
    struct Student student;
    char format[] = "NNN NNN NN"; /* "123 456 78" */
    
    printf("Enter phone number: ");
    fgets(student.textForm, getSize(format) + 1, stdin); 
    // The gets() function is deprecated in newer versions of the C/C++ standards.
    
    if(isValid(student.textForm, format))
    {
        convertToNumber(&student);
        printf("Result: %llu", student.numberForm);
    }

    return 0;
}

void convertToNumber(struct Student * const student)
{
    int size = getSize(student->textForm) - 2;
    unsigned int temp[size];
    student->numberForm = 0ull;
    
    for(int i = 0, j = 0 ; i < getSize(student->textForm) ; ++i)
        if(isdigit(student->textForm[i]))
            temp[j++] = student->textForm[i] - '0';
    
    for(size_t i = 0 ; i < size ; ++i)
        student->numberForm += temp[i] * power(10, size - i - 1);
}

bool isValid(const char * const input, const char * const format)
{   
    if(getSize(input) == getSize(format))
    {
        size_t i;

        for(i = 0 ; i < getSize(input) ; ++i)
        {
            if(format[i] == 'N')
            {
                if(!isdigit(input[i]))
                    break;
            }
            else if(format[i] == ' ')
            {
                if(input[i] != format[i])
                    break;
            }
        }

        if(i == getSize(input))
            return true;
    }
    return false;
}

unsigned long long power(int base, unsigned int exponent)
{
    unsigned long long result = 1;
    
    for(size_t i = 0 ; i < exponent ; ++i)
        result *= base;
    
    return result;
}

size_t getSize(const char * const input)
{
    size_t size = 0;
    
    while(input[++size] != '\0');
    
    return size;
}

This program works as follows:

Enter phone number: 123 465 78
Result: 12346578
Sercan
  • 4,739
  • 3
  • 17
  • 36
1

You can use fgets to parse an input with spaces and all:

#include <stdio.h>

#define SIZE 100

int main() {
    
    char str[SIZE];

    fgets(str, sizeof str, stdin); // parses input string with spaces
                                   // and checks destination buffer bounds
                                     
}

If you then want to remove the spaces you can do that easily:

#include <ctype.h>

void remove_white_spaces(char *str)
{
    int i = 0, j = 0;
    while (str[i])
    {
        if (!isspace(str[i]))
          str[j++] = str[i];
        i++;
    }
    str[j] = '\0';
    
}

Presto, this function will remove white spaces from the string you pass as an argument.

Live demo

Input:

12 4 345 789

Output:

124345789

After that it's easy to convert this into an unsigned integral value, you can use strtoul, but why would you store a phone number in a numeric type, would you be performing arithmetic operations on it? Doubtfully. And you then save to a file, so it really doesn't matter if it's a string or numeric type. I would just keep it as a string.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
1

It is generally better to store a telephone number as a string, not as a number.

In order to read a whole line of input (not just a single word) as a string, I recommend that you use the function fgets.

Here is an example based on the code in your question:

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

struct Student{
   char phone_number[50];
};

int main( void )
{
    //open output file (copied from code in OP's question)
    FILE *filePtr;
    filePtr = fopen("std_info.txt","w");

    //other variable declarations
    struct Student Student1;
    char *p;

    //prompt user for input
    printf( "Enter student's phone number: ");

    //attempt to read one line of input
    if ( fgets( Student1.phone_number, sizeof Student1.phone_number, stdin ) == NULL )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to find newline character, in order to verify that
    //the entire line was read in
    p = strchr( Student1.phone_number, '\n' );
    if ( p == NULL )
    {
        printf( "line too long for input!\n" );
        exit( EXIT_FAILURE );
    }

    //remove newline character by overwriting it with terminating
    //null character
    *p = '\0';

    //write phone number to file
    fprintf( filePtr, "%s\n", Student1.phone_number );

    //cleanup
    fclose( filePtr );
}
Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
-2

Use string for that purpose and trim the spaces from string and then convert the given number into integer using atoi function, to use atoi you must include stdlib.h header file. For example

#include<stdio.h>
#include<stdlib.h>
int main(){
        char str[] = "123456";
        unsigned long long int num = atoi(str);
        printf("%llu", num);
}
Anonymous
  • 318
  • 4
  • 14
  • 1
    Using `atoi()` for an `unsigned long long` is going to yield unhappiness. You probably need `strtoull()`. – Jonathan Leffler Jan 15 '22 at 12:13
  • 2
    Telephone numbers are best treated and stored as special strings, not as numbers. – Cheatah Jan 15 '22 at 12:15
  • this still doesnt answer to my question of how to take input with spaces, i want to take "565 856 12" and print it to the file. but when compiler sees the space, it stops taking the variable – user9560064 Jan 15 '22 at 12:31