#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?
Related
I'm fairly new to all of this and I somehow can't seem to find a solution. Although I have no syntax errors, the program doesn't work as its supposed to.
I want the users to input two firmnames [int read ()] which get saved under the char arrays x and y. From there I want to compare them both if they are equal or not [int equal()]. After that, if they are equal, I want to print out accordingly[int stringconcatenate()]
I want **read() ; equal() ; stringconcatenate() to be connected with the main program and work accordingly.
I'm trying to take the entered "firmnames" and then save them under the array name x and y. (which doesn't work as it should).. Am I missing something?
this is what I get if I enter "test" for both firmnames:
Please type in Firmname 1: test
Please type in Firmname 2: test
Strings are unequal.
a & ³■a are different.
Any tips are very much appreciated.
Btw, I'm not allowed to use strcmp, hence my unorthodox code.
#include <stdio.h>
#include <ctype.h>
int read (){
char x[50];
char y[50];
printf("Please type in Firmname 1:\t");
scanf("%s", &x);
printf("Please type in Firmname 2:\t");
scanf("%s", &y);
}
int Equal (char x[], char y[]){
char *p1,*p2;
int f = 0;
p1=x;
p2=y;
while (*p1!= '\0' || *p2!='\0'){
if(*p1 != *p2){
f=1;
break;
}
p1++;
p2++;
}
if (f==0)
printf("\nStrings are equal.\n");
else
printf("Strings are unequal.");
}
int stringconcatenate(char x[], char y[]){
char *p1,*p2;
p1=x;
p2=y;
if (*p1==*p2){
printf ("\n %s is the only one.", x);
}
else
printf ("\n %s & %s are different.", x, y);
return 0;
}
int main(){
char s1[50], s2[50];
printf("Program Compare\n\n");
read ();
Equal (s1, s2);
stringconcatenate(s1, s2);
return 0;
}
The basic problem is your read function which is wrong.
In your original code, x and y are local variables which exist only during the execution of the read function; afterwards the are discarded and cannot be used any more. Furthermore there is no reason why x and y would be magically copied to s1and s2.
This is the corrected version of read:
int read(char x[50], char y[50]) { //
printf("Please type in Firmname 1:\t");
scanf("%s", x); // use x and not &x, x is already an address
printf("Please type in Firmname 2:\t");
scanf("%s", y); //
}
and call it like this from main:
read(s1, s2);
There are more problems in your code:
Equal and read are int function, but they don't return anything, so they should rather be void functions.
Rather than displaying if the strings are equal or not, Equal should return e.g. 1 if the strings are equal and 0 if they are not and the display of the result should be done in main. This is not a programming error but rather a design error.
your strconcatenate function doesn't even attempt to do a string concatenation. I'm not sure what you're trying to achieve with this code.
Note, I assume this is an assignment, so I will only include some pointers (no puns intended) so that you can correct the mistakes by yourself.
Ok, let's address problems function by function.
int read (){
char x[50];
char y[50];
printf("Please type in Firmname 1:\t");
scanf("%s", &x);
printf("Please type in Firmname 2:\t");
scanf("%s", &y);
}
This function simply reads two strings from standard input (stdin from now on) and then it throws them away. Neither x nor y are in some ways returned to the main function, that means that, when you call read in the main, and I assume you expect s1 and s2 to have, respectively, the value of x and y, s1 and s2 do not change. What you can do to address this problem is to pass a pointer to s1 and s2 to the read function. In fact, in the C language arrays used in expression have the same value of the pointer to their first element (for instance, if I use s1 in an expression, it gets converted to the pointer to the first element of s1). That being said, please pass |(the pointers of) s1 and s2 to the read function and use scanf on them. Another problem with this function is that it says that it returns an int, but it fact it returns nothing. Please change the function to address this problem.
(There is another problem with the read function that is "what if I input, for instance, the entire GPL license? The program will not be happy and it might crash. Please have a look at cppreference).
The second function I see is this:
int Equal (char x[], char y[]){
char *p1,*p2;
int f = 0;
p1=x;
p2=y;
while (*p1!= '\0' || *p2!='\0'){
if(*p1 != *p2){
f=1;
break;
}
p1++;
p2++;
}
if (f==0)
printf("\nStrings are equal.\n");
else
printf("Strings are unequal.");
}
Please, don't use general purpose functions like this to print to standard output. Make equal return a value (for instance 0 if the strings are equal, 1 otherwise).
The while loop condition is wrong: what you're saying is that "if *p1 is not '\0' OR *p2 is not '\0', then go forward with the loop. If one is '\0' but the other is not, the loop will go forward.
I can't figure out what you want to achieve with the stringconcatenate function. Please explain.
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.
I need to be able to read in a word from a file one at a time and then be able to sort the text into a struct to track how many times words have been repeated however whenever I try to point to a specific word in the file I'm getting the whole file value instead of the specific word I'm trying to retrieve. apologies if the solution is simple, I still struggle with the different types of pointers and file commands
#include <stdlib.h>
#include <stdio.h>
char *inputFilename;
char *outputFilename;
char inputText[5000];
char outputText[5000];
int inputFlag;
int outputFlag;
int readfile(char **data){
FILE *input;
input = fopen(inputFilename, "rb");
int len = sizeof(*input);
printf("input length is %d\n", sizeof(char));
//First value is number of integers
int size;
fread(&size, sizeof(char), 0, input);
//allocate memory for that number of values
*data = (char*)malloc(sizeof(char) * size);
//Read in rest of data
fread(*data, sizeof(char), size, input);
//return size
printf("size is %d\n", size);
return size;
}
int valueSearch(char *vData, int argCount, char **argv){
for(int argLoop = 0; argLoop < argCount; argLoop++){
//If vData is detected then the next argument is the input file name
if(strcmp(argv[argLoop], vData) == 0){
return argLoop + 1;
}
}
return 0;
}
int main(int argc, char **argv){
char *data;
inputFlag = valueSearch("-i", argc, argv);
printf("input flag is %d\n", inputFlag);
inputFilename = argv[inputFlag];
if(inputFlag == 0){
printf("Please enter the text you would like to sort: ");
fgets(inputText, 5000, stdin);
}
else{
int size = readfile(&data);
}
int i = 0;
//Value that should be placed into struct
printf("readfile value 0:\n%s\n", data[i]);
free(data);
return 0;
}
Your last printf uses %s instead of %c. %s treats the argument as a pointer to a string (char array), and prints each byte until it encounters a byte of 0. You want %c, which prints out a single char.
Use %c instead of %s because %s is a identifier of string and that will print whole string.
printf("readfile value 0:\n%c\n", data[i]);
Hopefully it will work for you.
You need to become familiar with compiling with compiler warnings enabled, and then do not accept code until it compiles without warning or error.
You invoke Undefined Behavior on line 19 and again on line 76 by using improper conversion specifiers for int (instead of long int - line 19) and again as already noted on line 76 where you use %s instead of %c.
Further, you do not include string.h which is required for the use of strcmp on line 41. There is no declaration for strcmp so your compiler makes a guess at an implicit declaration.
You will also find unused variables len and size in your code. (lines 17 and 69, respectively).
All of these problems are readily apparent from your compiler output if you compile with -Wall -Wextra (and if wanted -pedantic) on gcc, with -Weverything on clang, or /Wall with VS (cl.exe) (you may want /W3 on VS as /Wall means all (and you will have to individually disable a handful of warning there with /wdXXXX where XXXX is the code for the warning you wish to disable).
While not an error, the standard coding style for C avoids the use of camelCase or MixedCase variable names in favor of all lower-case while reserving upper-case names for use with macros and constants. It is a matter of style -- so it is completely up to you, but failing to follow it can lead to the wrong first impression in some circles.
Moral of the story -- (1) enable compiler warnings, and (2) do not accept code until it compiles cleanly -- without warning. Letting your compiler help you write better code will eliminate a large percentage of the errors you spend time chasing :)
I've just started learning how to program in C and I'm trying to make a program that accepts a number and uses it as an ASCII value to return the ASCII character associated with that value.
The program works when the parameters are predefined but when I introduce the scanf function it compiles but doesnt give me the same results.
Here is my code :
#include <stdio.h>
int main(void)
{
question2();
return 0;
}
int question2(void)
{
int myInt = 65;
scanf("%d", myInt);
char ch = myInt;
printf("%c",ch);
return 0;
}
Cheers and thanks for any help guys.
You need to pass the address of myInt to scanf() (the compiler should have emitted a warning for this):
scanf("%d", &myInt);
You should also check the return value of scanf() to ensure myInt was actually assigned to. scanf() returns the number of assignments made, which in this case is expected to be 1:
if (1 == scanf("%d", &myInt))
{
}
Note that int has a larger range values than a char so you should check that the value stored in myInt will fit into a char. There are macros defined in the header limits.h that you can use to check:
if (1 == scanf("%d", &myInt))
{
if (myInt >= CHAR_MIN && myInt <= CHAR_MAX)
{
printf("%c\n", (char) myInt);
}
else
{
printf("%d out-of-range: min=%d, max=%d\n",
myInt, CHAR_MIN, CHAR_MAX);
}
}
The compiler should have also emitted an implicit function declaration warning with respect to question2(). To correct, place the definition of question2(), or a declaration for question2(), prior to main().
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);
}