Scanning, Checking, Converting, Copying values ... How to ? -- C -- - c

Its been a while now and im still trying to get a certain code to work. I asked some question about different commands etc. before, but now I hope this is the final one (combining all questions in one code).
I basically want to :
*Scan an input (should be character ? )
*Check if its a number
*If not, return error
*Convert that character into a float number
*Copy the value to another variable ( I called it imp here)
Here is what I came up with :
EDITED CODE*
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
main(){
int digits;
float imp=0;
char* alpha;
do{
printf("Enter input\n\n");
scanf("\n%c",alpha);
digits=isdigit(alpha);
if(digits==0){
printf("error\n\n");
}
imp=atof(alpha);
}while(digits==0);
}
The problem is this code does not work at all ... It gives me that atof must be of a const char and whenever I try changing it around, it just keeps failing. I am frustrated and forced to ask here, because I believe I have tried alot and I keep failing, but I wont be relieved until I get it to work xD So I really need your help guys.
Please tell me why isnt this code working, what am I doing wrong ? I am still learning C and really appreciate your help :)
EDIT
Error given atm is :
Argument no 1 of 'isdigit' must be of type 'const int', not '<ptr>char'
EDIT
This code compiles fine, but crashes when an input is entered.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
main(){
int digits;
float imp=0;
char* alpha=0;
do{
printf("Enter input\n\n");
scanf("\n%s",alpha);
digits=(isdigit(alpha[0]));
imp=atof(alpha);
}while(digits==0);
}

Why not have scanf do the atof conversion for you?
#include <stdio.h>
int main()
{
float imp=0;
while (1)
{
printf("Enter input\n\n");
if (scanf("%f", &imp) < 1) break;
}
return 0;
}
Your most recent example is failing because alpha is a NULL pointer. Declare it as char alpha[40]; to allocate space for it. You'll probably want to use %40s in your format string to prevent scanf from overflowing alpha.
Also, use strtod instead of atof and you'll know whether the conversion was successful (better than your method of using isdigit which will fail on a negative integer).

You probably need to use %s instead of %c and to put it in char array (char*). You also probably get an error that you need to use const char* and not const char.
You don't want to read just one character - you want to read an entire string...
EDIT:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
main(){
int digits,i;
float imp=0;
char* alpha = malloc(100); /* 100 is for example */
do{
printf("Enter input\n\n");
scanf("\n%s",&alpha);
for (i = 0; i != 100; ++i)
{
if (alpha[i] == '\0')
break;
if (!isdigit(alpha[i]))
{
printf("error\n\n");
return ...;
}
}
imp=atof(alpha);
}while(true);
}

Related

Check palindrome input if string or int

Hi everyone I want check input(char or int) polindrome or not but I can't do this. Can you help me ? I have error message
"invalid conversation char to char*"
I think this is a simple problem but I couldn't solve it already. Thank you for your help.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main()
{
int r,sum=0,temp;
char a;
char *b = &a;
printf("Enter a string or number\n");
scanf("%c", &a);
if ( isalpha( a ) )
{
b = a;
strrev(b);
if (strcmp(a, b) == 0)
printf("The string is a palindrome.\n");
else
printf("The string isn't a palindrome.\n");
}
else if ( isdigit( a ) )
{
temp=a;
while(a>0)
{
r=a%10;
sum=(sum*10)+r;
a=a/10;
}
if(temp==sum)
printf("palindrome number ");
else
printf("not palindrome");
}
return 0;
}
Since you mentioned that you are a student and want to learn C, I am not going to write a code but will try to point you into the right direction.
To solve this, you need:
Get a alphanumeric string
Check if it's a palindrome (you have several options there)
First of all, to get a string, you have in your code:
char a;
scanf("%c", &a);
A hint: this is only getting you one character. To get a string, you first need to allocate an array instead of one single char, and then use scanf with a different argument, not %c.
This part of the task is completely independent of the second part. I recommend first to make sure that this part works before proceeding further. You can do it by getting a string and then immediately printing it. This way you can see what you are actually dealing with.
Once you have your string, proceed with analyzing it. You could revert it and then compare to original (that's what your code is suggesting), but it's probably easier to do something like this:
Find string length
Compare each symbol in the string with its symmetrical counterpart. For example, if string length is 10, you'll need to compare symbol #0 with symbol #9, symbol #1 with symbol #8 etc. etc. Hint: you'll need to use a loop here.

Not able to take string and float as input in a single line in C

What I have till now is this. I am not able to figure out how to take the input as mentioned and solve this problem?
#include<stdio.h>
#include <stdlib.h>
#include<float.h>
int main()
{
char s[50];
float mil,min=FLT_MAX;
while(scanf("%s#%f",s,&mil)!=-1)
{
printf("%s\n",s);
if(mil<min)
min=mil;
}
}
EDIT: My problem is that when I print the string s inside the loop, "Zantro#16.15" is printed whereas I want only "Zantro" to be stored in s and 16.15 to be stored in mil
%s scans up until a whitespace. Scan up until a # instead.
while (scanf("%[^#]#%f", s, &mil) == 2)
Remember to specify the maximum buffer size in the scanning format to protect against overflows:
while (scanf("%49[^#]#%f", s, &mil) == 2)
Well the scanf function can not easily determine, that you want the # sign to be a delimiter. Therefore you need to add an extra step to split up the strings into proper parts and store them for later comparison.
Have a look at strtok function in c.
http://www.c-howto.de/tutorial/strings-zeichenketten/string-funktionen/string-zerteilen/
Here is a solution that prints the requested string:
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
int main()
{
char s[50];
char mins[50];
float mil,min=FLT_MAX;
int rc;
int done=0;
while (done == 0)
{
rc = scanf("%49[^#]#%f", s, &mil);
if (rc != 2)
{
done = 1;
continue;
}
if (mil < min)
{
min = mil;
strcpy(mins, s);
}
}
printf("%s\n", mins);
return 0;
}
Execution:
./sc
Zantro#16.15
Zirty#12.5
Gamry#9.8
Gamry
#include<stdio.h>
#include <stdlib.h>
#include<float.h>
int main()
{
char s[50];
float mil, min = FLT_MAX;
while (scanf("%[^#]#%f", s, &mil) == 2)
{
printf("%s\n", s);
if (mil < min)
min = mil;
}
}
Input:Zantro#16.15Zity#12.5Gamry#9.8
OutPut:
Zantro
Zity
Gamry
If you want to split your input in the scanf to string and float, you have to write those two types separately. For example, ("%s %f"). This string tells the function, what will be the arguments types. Therefore, if you write it like this ("%s#%f") the scanf function has a problem to understand, what will be the inputs types. In addition, if you write ("%s #%f") it will get two inputs like this " #". Your problem here is the space between the two arguments. Because, I didnt find how to get the input without this space. I'm recommending you to try splitting the input in another way.
For example, take one string that holds the intaier input to string buffer-> scanf("%s",sBuffer).
and split that to different variables after that.

strings and isdigit function

#include<stdio.h>
#include<string.h>
#include<ctype.h>
int digit(s1);
int main()
{char s1[10];
printf("\n Type anything you want:\n");
gets(s1);
printf("The number of digits is:%d",digit(s1));
return 0;
}
int digit(char* s1)
{
int i=0;
while(*s1)
{
i+= !!isdigit(*s1++);
}
return i;
}
This is my code, I need to find out is the element that I give a digit or not.
I change it into void digit and it runs perfectly now.
isdigit is a standard C function declared in <ctype.h>. Your function conflicts with it. Choose a different name for your function.
That will avoid the compiler message about conflicting types, but there are other errors in your program you will need to fix.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int count_digits(const char *s1);
int main()
{
char s1[20];
printf("\n Type anything you want:\n");
fgets(s1, sizeof(s1), stdin);
printf("The number of digits is:%d", count_digits(s1));
return 0;
}
int count_digits(const char* s1)
{
int count = 0;
while(*s1)
{
count += !!isdigit(*s1++);
}
return count;
}
The code you provided has several major issues. If the lecture says to use gets(), throw it into the trash, use fgets() instead. The reason why, you can find in this link:
Why is the gets function so dangerous that it should not be used?
Apart from that, The lecture seems to not even provided you the knowledge to correctly pass parameters or to output values of variables correctly.
I recommend you to read a good C starting book, f.e. this. A list of recommended books can be also found here:
The Definitive C Book Guide and List
To only focus one issue, the output:
printf("There are %d digits in your string.");
This use of printf() is incorrect. Where shall the value specified by %d come from? The %d format specifier is missing a corresponding argument which points to an integer value or an int variable, like:
int a = 10;
printf("a = %d",a);
%d requires a matching argument of type int to actually print a value. Else the behavior is undefined.
This shall in all cases give a diagnostic. Never ignore compiler warnings.
Why should I always enable compiler warnings?

Getting an infinite running program when using scanf

I'm getting an infinite running programm when I use the following code to read a string from keyboard and save it within a structured vector.
scanf("%s", strk_zgr_fp->bezeichnung, (int)sizeof(strk_zgr_fp->bezeichnung - 1));
Simply nothing happens after this line is reached and the program runs infinitly.
I know scanf() isn't recommended. We're using it only within our C beginners course and I want you to keep it in mind, ie please don't recommend other function rather than above mentioned for the moment.
Any help is much appreciated, thanks in advance.
#include <stdio.h>
typedef struct {
int nummer;
char bezeichnung;
int menge;
float preis;
} artikel;
void eingabe_artikel(artikel *strk_zgr_fp, int i_fp);
void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp);
void main(void) {
artikel artikelliste[10];
artikel *strk_zgr;
int anzahl;
do {
printf("Bitte eine #Artikel eingeben [<= 10]: ");
scanf("%d", &anzahl);
if(anzahl < 1 || 10 < anzahl)
printf("\nEs wurde eine falsche #Artikel eingegeben.");
} while(anzahl < 1 || 10 < anzahl);
for(int i = 0; i < anzahl; i++)
eingabe_artikel(&artikelliste[i], i);
int i;
for(strk_zgr = artikelliste, i = 0; strk_zgr < artikelliste + anzahl;
strk_zgr++, i++)
ausgabe_artikel(strk_zgr, i);
}
void eingabe_artikel(artikel *strk_zgr_fp, int i_fp) {
printf("\nBitte den %d. Artikel eingeben: ", ++i_fp);
printf("\nNummer: ");
scanf("%d", &strk_zgr_fp->nummer);
printf("Bezeichnung: );
scanf("%s", strk_zgr_fp, (int)sizeof(strk_zgr_fp->bezeichnung - 1)); /* <-- */
printf("Menge: ");
scanf("%d", &strk_zgr_fp->menge);
float preis;
printf("Preis: );
scanf("%f", &preis);
strk_zgr_fp->preis = preis;
}
void ausgabe_artikel(artikel *strk_zgr_fp, int i_fp) {
printf("\n%d. Artikel: ", ++i_fp);
printf("\nNummer:\t%d", strk_zgr_fp->nummer);
printf("\nBezeichnung:\t%s", strk_zgr_fp->bezeichnung);
printf("\nMenge:\t%d", strk_zgr_fp->menge);
printf("\nPreis:\t%.2f EUR\n", strk_zgr_fp->preis);
}
NetBeans Version
Complier Version
Many problems in the code. Please at least fix the missing ending quotes on the printf() calls.
Now to the beef:
1) Your structure is wrong. 'Bezeichnung' is defined as a single character, not a string.
typedef struct {
int nummer;
char bezeichnung[100];
int menge;
float preis;
} artikel;
2) You cannot use scanf() in the way you did. If you want to limit the input length (which always is a good idea), you need to pass the maximum length into the format string.
Do you nee to use scanf()?? Because it gets messy from here on....
As your maximum input length might be variable or subject to change (see 1.), you need to build the format string for scanf. Something like this:
char format_str[15];
format_str[0] = '%';
//Dont use itoa(), it is not C standard.
sprintf(&format_str[1], "%d", (int)sizeof(strk_zgr_fp->bezeichnung) - 1);
strcat(format_str, "s");
scanf(format_str, strk_zgr_fp->bezeichnung);
Hope that gets you going.
PS: You need to include string.h for strcat().
I tried it out and it worked fine for me. Not sure on this sprintf() function. Could you please explain why I'm supposed to use it? By now, I used this code: char format_str[20]; format_str[0] = '%'; strcat(format_str, "s"); printf("Bezeichnung: "); scanf(format_str, strk_zgr_fp->bezeichnung);
While that works, you are missing out on limiting the length of the user's input. That is why I proposed using sprintf() to create a (sub)string containing the maximal allowable length of the user input, depending on how large your 'bezeichnung' is defined in the struct. Suppose 'bezeichnung' has a limit of 100 characters, you would want to limit the input to 99 (+1 for the zero-termination), so you want a scanf format string like this: "%99s".
chux has provided a much more compact version of my three lines, but I think, in the beginning, you will have it easier to just assemble such format strings piece by piece, at the same time learning how to a) change individual characters in a string, how to use sprintf() in a basic way, and how to concatenate strings with strcat().
There was another example which I did and the course leader provided a scanf() function like this to read a string: scanf("%s", &(strk_zgr_fp->bezeichnung));. I thought when I'm reading a string the address operator isn't used. The only difference is the address operator now is used and the element was put into brackets.
Now, I think this is bad practice. It works, but is superfluous. Consider this small code snippet:
#include <stdio.h>
#include <stdlib.h>
struct test{
int i;
char a_str[10];
};
int main()
{
struct test a_test;
printf("Normal array adress taking: %p\n", a_test.a_str);
printf("Using '&' to take adress of array: %p\n", &(a_test.a_str));
return 0;
}
Hope that helps.

Searching for a character in an array by incrementing a pointer?

So the function I declared doesn't seem to working as intended, and even so, I don't think that's the proper way to compare characters by incrementing the pointer, so I'm generally lost here. To be honest, pointers have always confused me and I really need to learn how to use them if I am going to get better at C. Thanks anyone for any help!
Here's the code I have, and if this helps, the purpose of the program is for you to enter a line of text, enter a single character to search in that line of text, and then find those characters using CharIsAt. (Will add the following later) the values stored in "found" will then be printed as well.
#include <stdio.h>
#define SIZE 41
int CharIsAt(char *pStr,char ch,int loc[],int mLoc);
int main(void){
char array[SIZE],search;
int found[SIZE],chars;
printf("Enter a line of text(empty line to quit): ");
while (fgets(array,SIZE, stdin)!=NULL && array[0]!='\n')
{
printf("Enter a character to search: ");
search=getchar();
chars=CharIsAt(array,search,found,SIZE);
}
return 0;
}
int CharIsAt(char *pStr,char ch,int loc[],int mLoc){
//Searches for ch in *pStr by incrementing a pointer to access
//and compare each character in *pStr to ch.
int i,x;
for (i=0;i<mLoc;i++){
if (strcmp(pStr[i],ch)==0){
//Stores index of ch's location to loc
loc[i]=pStr[i];
x++;
}
}
//Returns the number of times ch was found
return x;
}
EDIT: Flipped sign around in the for loop. Now the program gives me a "stopped working" error.

Resources