Input numbers (may with leading zero ) but output them without leading zero - c

I need to preserve any leading zeroes in the input, so I take the digits in as chars and then convert them back to integers using the ctoi() function, as shown in this code:
#include<stdio.h>
#define ctoi(a) a-'0'
int main() {
int n;
char ch;
scanf("%c",&n);
ch=ctoi(n);
printf("%d",n);
}
But that code didn't work. What is the problem?
Input:
001
0123
78
000123
Expected Output:
1
123
78
123
But I got:
1
1
7
1

when you store the number as an integer, you only store the actual number, not the formatting used to make that number. If you want to preserve the formatting as is you either need to store it as a string or some other means of storing the original formatting.
int n = 10; // only stores a number in memory
char text[10] = "00010"; // stores any text, but can not be used for number arithmetic as stored here

Related

c integer starts with 0

How can I print the 0 value in front of integer
if user enters 05 printing 05. %d just ignores the 0
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
x = 05;
printf("%d", x);
return 0;
}
output = 5
First of all, realize that constants with a leading 0 are interpreted as octal, not decimal. 05 and 5 are the same, but you'll have an issue with something like 09.
You can specify a minimum output field width like so:
printf( "%2d\n", x ); // minimum field width of 2, pad with blanks
or
printf( "%*d\n", 2, x ); // minimum field width of 2, pad with blanks
To pad with a leading 0, use
printf( "%02d\n", x ); // minimum field width of 2, pad with 0
or
printf( "%0*d\n", 2, x ); // minimum field width of 2, pad with 0.
Use the format specifier %02d:
#include <stdio.h>
int main(void)
{
int x;
x = 05;
printf("%02d\n", x);
return 0;
}
If a user can enter 05 or 5 and you want to distinguish between the two you need to read the input as a string instead. As mentioned by user3121023, note that integers with a leading zero are interpreted as octal numbers, for instance 010 equals 8.
Here is the full documentation of printf:
https://pubs.opengroup.org/onlinepubs/9699919799/
printf("%02d", x);
The zero represents how many digits will the zero padding be so if you wanted to do the same with 10 for example it should be 03 hope this helps.
If the user enters “05” and you read it using scanf with %d or something similar, the only result you will get from the scanf is the value five; there will be no indication whether the user entered “05” or “5”. If you need to know specifically what the user enters, you need to read the input as strings or characters.
If you use ”0” as the first digit of a constant in C source code, it introduces an octal constant, so that 010 represents eight.
If you want to print a leading “0” before a number, you can simply include it literally in the format string: printf("0%d", x);.
If you want to print the string with at least a certain number of digits, with as many leading zeros as necessary to give that many digits, you can use “0n” in the format specification, where “n” is the number of digits: printf("%02d", x);.
If you want to combine the above and print a zero in front of the number if and only if the user entered a zero in front of the number, you need to write source code that adjusts what is printed based on what was seen in input. (The easiest way to do this may be to record the characters the user types and just print those exactly.)

How to split string (character) and variable in 1 line on C?

How can I split character and variable in 1 line?
Example
INPUT
car1900food2900ram800
OUTPUT
car 1900
food 2900
ram 800
Code
char namax[25];
int hargax;
scanf ("%s%s",&namax,&hargax);
printf ("%s %s",namax,hargax);
If I use code like that, I need double enter or space for make output. How can I split without that?
You should be able to use code like this to read one name and number:
if (scanf("%24[a-zA-Z]%d", namax, &hargax) == 2)
…got name and number OK…
else
…some sort of problem to be reported and handled…
You would need to wrap that in a loop of some sort in order to get three pairs of values. Note that using &namax as an argument to scanf() is technically wrong. The %s, %c and %[…] (scan set) notations all expect a char * argument, but you are passing a char (*)[25] which is quite different. A fortuitous coincidence means you usually get away with the abuse, but it is still not correct and omitting the & is easy (and correct).
You can find details about scan sets etc in the POSIX specification of scanf().
You should consider reading a whole line of input with fgets() or POSIX
getline(), and then processing the resulting string with sscanf(). This makes error reporting and error recovery easier. See also How to use sscanf() in loops.
Since you are asking this question which is actually easy, I presume you are somewhat a beginner in C programming. So instead of trying to split the input itself during the input which seems to be a bit too complicated for someone who's new to C programming, I would suggest something simpler(not efficient when you take memory into account).
Just accept the entire input as a String. Then check the string internally to check for digits and alphabets. I have used ASCII values of them to check. If you find an alphabet followed by a digit, print out the part of string from the last such occurrence till the current point. And while printing this do the same with just a slight tweak with the extracted sub-part, i.e, instead of checking for number followed by letter, check for letter followed by digit, and at that point print as many number of spaces as needed.
just so that you know:
ASCII value of digits (0-9) => 48 to 57
ASCII value of uppercase alphabet (A-Z) => 65 to 90
ASCII value of lowercase alphabets (a-z)
=> 97 to 122
Here is the code:
#include<stdio.h>
#include<string.h>
int main() {
char s[100];
int i, len, j, k = 0, x;
printf("\nenter the string:");
scanf("%s",s);
len = strlen(s);
for(i = 0; i < len; i++){
if(((int)s[i]>=48)&&((int)s[i]<=57)) {
if((((int)s[i+1]>=65)&&((int)s[i+1]<=90))||(((int)s[i+1]>=97)&&((int)s[i+1]<=122))||(i==len-1)) {
for(j = k; j < i+1; j++) {
if(((int)s[j]>=48)&&((int)s[j]<=57)) {
if((((int)s[j-1]>=65)&&((int)s[j-1]<=90))||(((int)s[j-1]>=97)&&((int)s[j-1]<=122))) {
printf("\t");
}
}
printf("%c",s[j]);
}
printf("\n");
k = i + 1;
}
}
}
return(0);
}
the output:
enter the string: car1900food2900ram800
car 1900
food 2900
ram 800
In addition to using a character class to include the characters to read as a string, you can also use the character class to exclude digits which would allow you to scan forward in the string until the next digit is found, taking all characters as your name and then reading the digits as an integer. You can then determine the number of characters consumed so far using the "%n" format specifier and use the resulting number of characters to offset your next read within the line, e.g.
char namax[MAXNM],
*p = buf;
int hargax,
off = 0;
while (sscanf (p, "%24[^0-9]%d%n", namax, &hargax, &off) == 2) {
printf ("%-24s %d\n", namax, hargax);
p += off;
}
Note how the sscanf format string will read up to 24 character that are not digits as namax and then the integer that follows as hargax storing the number of characters consumed in off which is then applied to the pointer p to advance within the buffer in preparation for your next parse with sscanf.
Putting it altogether in a short example, you could do:
#include <stdio.h>
#define MAXNM 25
#define MAXC 1024
int main (void) {
char buf[MAXC] = "";
while (fgets (buf, MAXC, stdin)) {
char namax[MAXNM],
*p = buf;
int hargax,
off = 0;
while (sscanf (p, "%24[^0-9]%d%n", namax, &hargax, &off) == 2) {
printf ("%-24s %d\n", namax, hargax);
p += off;
}
}
}
Example Use/Output
$ echo "car1900food2900ram800" | ./bin/fgetssscanf
car 1900
food 2900
ram 800

Reading the first line of a txt and converting it to int, but returning another value [C]

I've been trying to read a txt which has a specific structure:
The first line indicates the n-1 lines the whole txt file has.
All the other lines have the "structure" of a card (it's number and it's pattern).
ex: I have a txt which stores 13 cards, so the file in itself has 14 lines:
13
A T
2 P
3 D
13 P
2 P
4 C
8 D
11 T
8 C
9 C
10 T
9 T
7 P
(Note: T stands for clubs, D for diamonds, C for hearts and P for spades, it's in spanish).
I've tried extracting the first line to then create a dynamic array with the number given so that I can store each line in that array, but I fail to get the first value.
My code is:
#include <stdio.h>
#include <stdlib.h>
int leerLinea(){
char contenido[1];
FILE* pArchivo;
pArchivo = fopen("Mazo.txt","r");
if (pArchivo == NULL){
printf("No hay nada aqui!\n");
return 0;
}
else{
fgets(contenido,3,pArchivo);
printf("%s\n", contenido);
}
fclose(pArchivo);
return contenido[0];
}
int main(){
int a;
a = leerLinea();
printf("a's value is: %d\n",a);
return 0;
}
But when I run it I get:
13
a's value is: 49
Why is it returning other value, when it should be returning 13?
With fgets(contenido,3,pArchivo), you read in a string into a buffer that is to small for capturing at least 2 digits and the string termination character; For that statement, it should be at least char contenido[3].
The main issue is, however, that you mix strings with "pure" integral values, i.e. you read in a string but expect it to be converted correctly to a number simply by accessing the first digit of that string; Note that if contenido containded "13", contenido[0] would give character value '1', which in ASCII is 49.
To overcome this, read in the value as a number, i.e. using "%d"-format:
int leerLinea(){
int contenido = 0;
FILE* pArchivo;
pArchivo = fopen("Mazo.txt","r");
if (pArchivo == NULL){
printf("No hay nada aqui!\n");
return 0;
}
else{
fscanf(pArchivo,"%d",&contenido);
printf("%d\n", contenido);
}
fclose(pArchivo);
return contenido;
}
1 - Read a line of text with sufficient space for each character in the line, the line-feed and a null character. The below is 4 characters, so a buffer of 6 is needed.
13 P
Further, there is little gained by being so stingy with line buffers. Suggest 2x the maximize anticipated size to allow for some growth, leading/trailing whitespace.
#define LINE_MAX (4 + 1 + 1)
char contenido[LINE_MAX * 2];
2 - When reading a line, do not hard code in the 3, use sizeof() for consistent, easier to maintain code.
// fgets(contenido,3,pArchivo);
fgets(contenido, sizeof contenido, pArchivo);
3 - Rather than return the first character of a string (the code for the character '1' is 49), convert the string into an int/long with strtol() or atol(), etc. #Nicolas Guerin
// return contenido[0];
return atoi(contenido);
// or
return strtol(contenido, NULL, 10); // better
return atoi(contenido[0]);
The probleme you've got is that you return a char in an int function, every char as an integer value. That's true but not the decimal value of the char, the ascii value.
Atoi convert a char into an int.
ps: the way you do, it will only return 1 in the exemple

Treating numerical variables as text

I was not sure how to title this question, so I'll go straight to the code for you to see what I mean. Really new into this, so bear with me!
I have this code:
1 #include <cs50.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 int main(int argc, string argv[])
6 {
7
8 if (argc!=2)
9 {
10 printf("error!! Usage: ./caesar k\n");
11 return 1;
12 }
13
14 printf("Plaintext: ");
15 string text=get_string();
16
17 char k=argv[1][0];
18 int n=strlen(text);
19
20
21 for (int i=0; i<n; i++)
22 {
23 if(text[i]>='a' && text[i]<='z')
24 {
25 printf("Cyphertext: %c\n", text[i]+k);
26 }
27 }
28 }
What's its purpose?
Well, given a text, it adds k to every character. Which means that, for abc, and k=1, the output would be bcd; for abc and k=3, output would be def.
Now, it is imperative that k is given as a command line argument.
What do I want to do?
Just take k (which is a number), add it to every character of the input string text, and voilà.
Since every letter is a number in ASCII, adding a number can change the character, so... it should work. [I am still trying to figure out how ASCII works, and when do char show up like charcters and not numbers... but anyway].
What is going on?
First, I am having trouble declaring k as an int or char. In line 17, -and although k is a number(!)- the IDE forces me to declare a string or char*: if I declare k as int I receive an error; if I declare char I receive an error too, unless I declare it not only as k=argv[1] but as k=argv[1][0], as shown in the code above.
Second, executing the code above, this is the input/output (the name of the program is caesar):
$./caesar
error!! Usage: ./caesar k
$./caesar 1
Plaintext: a
Cyphertext: (nothing...)
Third, given the error above, I changed the code in line 25 from this:
printf("Cyphertext: %c\n", text[i]+k);
to this:
printf("Cyphertext: %s\n", text[i]+k);
which returned this error message:
caesar.c:25:38: error: format specifies type 'char *' but the argument has
type 'int' [-Werror,-Wformat]
printf("Cyphertext: %s", text[i]+k);
~~ ^~~~~~~~~
%d`
error message I do not understand, given that neither text nor k are int.
Anyway, changing %c to %s did not work, so I tried with %i instead:
printf("Cyphertext: %i\n", text[i]+k)
which at least returned something:
$./caesar 1
Plaintext: a
Cyphertext: 146
$./caesar 5
Plaintext: a
Cyphertext: 150
So, basically, it is adding k to 150 -which is 'û' in ASCII, so...(?).
And, finally, apart from the fact the program returns a number I do not understand, I thought I could make it show up like letters/non-numerical characters adding this:
printf("Cyphertext: %i\n", (char)text[i]+k);
but it actually does not, the program returns exactly the same last output shown above.
So well, this is a much longer question than I expected, but I hope someone in here has the patence and proficency to answer it.
Thank you very much!
Command line arguments are always passed in as strings. Just because your program expects the first argument to look like a number doesn't necessarily mean that a number gets passed in.
So when you get the first character in the string via argv[1][0], you're not picking up the value 1 but the character 1. Assuming ASCII is used for characters, this character has an ASCII value of 49. So k in this case has the value 49.
You need to convert the argument to a number. You can use the atoi function for this:
int k = atoi(argv[1]);
If you simply want to convert a digit ('0'-'9') to a number, you can simply subtract the Ascii code for '0' from your input.
char digit;
int num = digit - '0';
You should check your input is within the range first.
if (digit < '0' || '9' < digit)
// error!!
The general purpose solution is
int k = atoi(argv[1]);
atoi takes a string and converts it to a number. The subtract solution above only deals with single digits, this will allow k > 9

Why am I getting random numbers when I try to increase the ascii value of a char?

int n = argv[i][j];
n = n + (int)argv[1];
/* I'm pretty sure the above part that is wrong. What I was hoping that this
would do is take the number the person put in and increase n by that number but
it isnt working*/
printf("%d\n", n);
i = the string numbers of the argument
j = the characters of the string
What I want is to make it so when someone types ./123 12 hi I want it to increase the ascii characters of h and i by 12 or whatever number they put in. When I test my code out with
./123 1 hi
I get an output of
-1081510229
-1081510228
instead of
105
106
which is i and j, the next letters of h and i
Libraries I'm using
stdio.h
studio50.h
string.h
argv[1] is a string (i.e, a null-terminated char array), casting it to int doesn't give the result you expected
You should use atoi to do the job. Or better, use strtol to get better stability.

Resources