I'm just learning how to code in C, It's my first non-web language and it's not off to a good start.
I have the following code:
//
// main.c
// Greeting
//
// Created by Austen on 2013-06-27.
// Copyright (c) 2013 Austen. All rights reserved.
//
#include <stdio.h>
int main()
{
int confirm[100];
char name[100];
char mood[100];
printf( "Please enter your name: " );
scanf("%s", name);
printf( "Hey there, %s . How are you? ", name);
scanf("%s", mood);
printf("Oh, you are %s?. Enter 1 or 0: ", mood);
scanf("%i", confirm);
if (confirm == 1) {
printf("Oh good!");
}
else {
printf("Make up your mind");
}
getchar();
return(0);
}
For some reason I just can't get it to work, I've had to change a few things in order for Xcode to stop moaning at me for so many reasons.
It's giving me a
warning: Comparison between pointer and integer int* and int
When I run it, even if I enter 1, it tells me to make up my mind.
Any help would be great, just so I know better next time. It's probably something really simple.
No need to create an array to hold an answer for confirm, a normal int will do:
int confirm;
But as scanf expects a pointer you need to pass its address like so:
scanf("%d", &confirm);
Finally, this - scanf("%i", confirm); should actually be this - scanf("%d", &confirm);.
%d is the standard formatting character for integer variables.
After that, everything compiled fine.
C is always pass by value, so there's no way for scanf to store the value you enter in the variable provided, unless it reaches inside memory where it resides and writes it to memory directly.
That's why it asks for the memory address of the variable, rather than the variable itself (you provide the address of something by prepending & to it).
Arrays are already treated as addresses (pointers to be more precise and pointers store the address of something) when passed as arguments to a function which is why you don't do it for them.
Some information on pointers and arrays here.
The reason you get that warning is because you're comparing an array of 100 integers to 1 integer. The correct code would be something like this
if (confirm[0] == 1)
or even easier
int confirm;
scanf("%d", &confirm);
if (confirm == 1)
Use %d for integers (for confirm)
Confirm is declared as an array, but you just want a plain integer. Remove the [100] after confirm in the declaration. It should just be;
int confirm;
The warning you got was because confirm was an array and it tried to compare the array's base address(confirm) to an integer value (1).
Whenever you declare an array, the base address of that array is available in the array name.(Eg. confirm here)
Replace the scanf line which takes confirm with
scanf("%d",&confirm);
it should work fine then
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 trying to beat string pointers in c, so I write this code but I didn't get the result that I expected.
I'm creating a string variable, and I want to pass it to a function that check if the string lenght is bigger than 10.
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
bool is_bigger_than_10(char *);
int main()
{
char *string1 = "";
int i = 0;
printf("Initial string: %s\n",&string1);
printf("Size is: %d\n",strlen(&string1));
printf("Give me one string: ");
scanf("%[^\t\n]s",&string1); //This scan allows me to enter string with spaces
printf("You write: %s\n", &string1);
printf("Size is: %d\n",strlen(&string1));
printf("String character by character:\n");
for(i = 0; i < strlen(&string1) ; i++)
{
printf("%c ",&string1[i]);
}
printf("\nNow let's check if it's bigger than 10\n");
printf("Answer is: %d",is_bigger_than_10(&string1));
return 0;
}
bool is_bigger_than_10(char *textx)
{
printf("%s --> %d > %d\n",&textx, strlen(&textx),10);
if(strlen(&textx) > 10)
{
return true;
}
else
{
return false;
}
}
The expected output should be:
Initial string:
Size is 0:
Give me one string: axel
You write: axel
String character by character:
a x e l
Now let's check if it's bigger than 10
a x e l --> 4 > 10
Answer is: 0
If yoy run that code and enter axel as the input string you will get this:
Initial string: $0#
Size is 3:
Give me one string: axel
You write: axel
String character by character: a b c d e
a x e l
Now let's check if it's bigger than 10
' --> 3 > 10
Answer is: 0
It's kind of weird, could some one help me to correct this code?
There are two things going on here:
First, your char pointer needs to point somewhere. With the line
char *string1 = "";
you create a pointer to a string literal, which you can't write to. (Obviously you can, given your output, but you just got lucky on a system that allows it.) Create a character buffer instead:
char string1[200] = "";
and ideally enforce the constant buffer limit when you read the string.
Second, you don't need all these &s. The & is not a magic marker that you have to prepend to all your arguments.
The & takes the address of a variable and passes it as a pointer. You need that when the called function needs to change the variable via the pointer. Printing doesn't need to change anything, so unless you want to print the address of a variable with %p, you shouldn't pass addresses. (In the special case of your program, you can just remove all ampersands with search and replace.)
When scanning, you need to change variables if you convert input to numbers or if you scan a char. The exception is when you scan strings with %sor %[...]: Here, you pass a char buffer (as a pointer to its first elements) and the function then fills that buffer.
The problem with scanf and printf is that the arguments after the format string are variadic, which means they will accept any arguments without type checking. The good thing is that most compilers can tell whether a format string matches the arguments and will issue warnings, it you enable them. Do yourself a favour and do that.
(Warnings will also tell you that you have type mismatches in functions where the type of the argument is known, such as your is_bigger_than_10.)
I am working on an assignment for school and am having trouble getting the correct output. I am unsure if there is a problem with my loop or a problem with the method of saving values with pointers. When I run the code I end up with something like this:
Output: There are 369224989 underscores and 0 exclamation points in the sentence.
The assignment specifies to use the prototype and the getchar() function to read the input. I feel like since the first value is so high it is an issue with my loop but I have been working on this for two days and haven't seen anything wrong with it (though I could be staring through it at this point).
In addition I get these warnings when I try and compile the program:
characters.c:28: warning: value computed is not used
characters.c:31: warning: value computed is not used
This makes me think that maybe it isn't communicating properly with the main function.
#include<stdio.h>
//this function prototype was required for the assignment
void count(int* num_, int* num_exclamation);
// intended to count the number of _ and ! in a string using pointers
int main()
{
int num_, num_exclamation;
count(&num_, &num_exclamation);
return 0;
}
void count(int* p_num_, int* p_num_exclamation)
{
char ch;
*p_num_ = *p_num_exclamation = 0;
//attempts to scan a string get the first character
printf("Enter a sentence: ");
ch = getchar();
//attempts to loop while incrementing if it is a ! or _
while(ch != '\n')
{
if(ch == '_')
*++p_num_;
if(ch == '!')
*++p_num_exclamation;
ch = getchar();
}
//prints result
printf("Output: There are %d underscores and %d exclamation points
in the sentence.\n", *p_num_, *p_num_exclamation);
}
This is the second time I have really interacted with pointers with the first being the other half of this assignment which is working properly. I am not particularly comfortable with them yet nor aware of all of their nuances. Any advice to get me looking in the right place would be greatly appreciated.
You have Undefined behavior in your code. *++p_num_; increments the pointer first and then it dereferences it. The value of it is not used. And this way, the pointer points to some memory which are not the variables you supposed it to be. Then you dereference it - that location contains indeterminate value and you print it. Accessing some memory which you don't have permisssion to is - UB.
(*p_num_)++
is the one you wanted. This holds for the other variable also - namely p_num_exclamation. Also return value of getchar is int not char - you should use int to hold the value returned by getchar.
I've been doing some exercise with structures to prepare for my upcoming exams, and I've run into a bit of trouble with this code.
// Creates a structure of type 'person' with a first name (nameF), last name (nameL), and the age (age)
typedef struct {
char nameF[20];
int age;
char nameL[40];
}person;
// Main function
int main() {
person ppl[2]; // We are creating 3 "people", whose information shall be printed into the file
// This loop takes user input to create the names and ages of 3 people
int i;
for (i = 0; i <= 2; i++) {
printf("\nEnter first name %d: ", i+1);
scanf("%s", &ppl[i].nameF);
printf("%s\n", ppl[i].nameF);
}
printf("It worked\n");
system("pause");
return 0;
}
It runs fine, but when the program exits, I keep receiving an error message from the Debugger that states: "Run-Time Check Failure #2. Stack around the variable 'ppl' was corrupted."
So I looked it up on Stack Overflow, this error appears when you go outside the bounds of a string. I don't understand where in my code I'm going out of bounds.
Here's an example of the output:
Enter first name 1: 'Adolfo'
Adolfo
Enter first name 2: 'Cecilia'
Cecilia
Enter first name 3: 'Tim'
Tim
Press any key to continue...
And then the error message pops up.
As you can see none of my inputs exceed the maximum amount of characters for the variable 'nameF', so there should be no reason for me to receive the error.
I saw someone on Stack Overflow mention that instead of making a character array:
char nameF[20];
One should instead write use dynamic memory allocation:
char * nameF = malloc(<enough bites to support any input);
Unfortunately, I don;t quite have a grasp of memory allocation yet, and when I attempted this code, I received all sorts of other errors, and my program wouldn't even run.
What is the mistake?
Also, I am not sure if this information is important, but I wrote this code using Visual Studio in C.
Edit: "char * nameF[20]" to "char nameF[20]" that asterisk was a leftover from my previous attempts at fixing the code, sorry.
Why are you allocating two structures then filling it with three responses?
Also, scanf is very dangerous as it can easily be abused to overwrite past a buffer. Look for routines (or write one) that limits the input to the length of the string.
hint: scanf man page might lead you to a better version.
Not meant as an answer, just made some adaptions allowing you to continue your work:
typedef struct {
char nameF[20]; // may take on 19 characters (+ string terminating char)
int age;
char nameL[40];
}person;
int main() {
person ppl[3]; // 3, not 2.
int i;
for (i = 0; i <= 2; i++) {
printf("\nEnter first name %d: ", i+1);
scanf("%s", ppl[i].nameF); // removed the &
printf("%s\n", ppl[i].nameF);
}
printf("It worked\n");
system("pause");
return 0;
}
After getting moderately comfortable with Java, i'm now trying to expand my horizon and try my hand at C programming. However, I cannot seem to wrap my head around the pointers in C, even with having visited multiple videos and websites.
The code below is supposed to take in two strings from the user, get the length of both of them and then compare the lengths against one another. The program should then return the longest of the two names (taking great care to return the length until newline, not the allocated size for the variable) by means of a pointer. So, when the user inputs 'Peterson'(name1) and 'Thisisareallylonglastname'(name2) the program should return 'Thisisareallylonglastname' by means of the pointer / name2 connection.
The problem I am having is that when trying to run the code (written in the Eclipse Neon C/C++ IDE, using the MinGW compiler) I get no output in the console. I am fairly certain I have set the path to my MinGW install correctly in windows, but to be sure I have also added the enviroment manually to the project. Between my confusion for pointers and generally being a crappy coder I am not sure what the (undoubtedly novice) mistake with my program is. I am not getting errors of any kind in the Neon IDE.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1:");
printf(size1);
int size2 = strlen(name2);
printf("Length of name 2:");
printf(size2);
if (size1 > size2)
{
ch = &name1;
}
else
{
ch = &name2;
}
if(!ch)
{
printf("The largest family name found is:");
printf(*ch);
}
return(0);
}
One major problem is that your final output is under the condition if (!ch) - which, in English, reads "if the pointer ch is null-valued". Since it points to one of two (non-null) memory locations, this check will never pass.
If you change that to if (ch) (or just omit the check, since we know it's not null) and fix the printf problems pointed out by others in the comments, I think you'll get better results.
A pointer to char and an array of char are both ways of representing strings in C and as such are the same type. The main difference being that with the array the memory is allocated at compile time and with a pointer you either assign an array to it (like you're trying to do) or dynamically allocate the memory.
So when you're doing
ch = &name1;
What you're actually doing is trying to assign a pointer to the string name1 to ch, which isn't the same type and should throw up an error. Instead you really want to be doing
ch = name1;
Conversely, *ch is the same as ch[0] - you're accessing the first character of the string so to print it out you want to have
printf("%s",ch);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
/* Two variables that take family names' input from the user with a maximum length of 256 */
char name1[256];
char name2[256];
char *ch = NULL;
printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
printf("Enter your last name for 1 :");
gets(name1);
printf("Enter your last name for 2 :");
gets(name2);
int size1 = strlen(name1);
printf("Length of name 1: %d", size1);
int size2 = strlen(name2);
printf("Length of name 2: %d", size2);
if (size1 > size2)
{
ch = name1;
}
else
{
ch = name2;
}
printf("The largest family name found is: %s", ch);
return(0);
}
This should do the trick. You should also use scanf("%s", str) instead of gets.
When you do char name1[256] name1 is "considered an pointer", so you must do ch = name1 not ch = &name1, because both ch and name1 are pointers.
when you did:
if(!ch)
{
printf...
}
you will only print if the ch is null, wich you don't want, because, in this case, you want to print if ch has a value so you should do:
if(ch)
{
printf...
}
also in c printf must receive the information about the variable you are trying to print, check printf examples to understand it
The main problem is that you're expecting printf to act as a polymorphic function like System.out.println, and it doesn't. The prototype for printf is
int printf( const char * restrict format, ... );
The first argument is always a character string; the string may contain conversion specifiers that control how any additional arguments are formatted.
So instead of writing:
printf("Length of name 1:");
printf(size1);
you'd write:
printf( "Length of name 1: %d\n", size1 );
or
printf( "Length of name 1: " );
printf( "%d\n", size1 );
The %d in the format string tells printf that the corresponding argument should have type int, and that you want to display its value as a string of decimal digits. See the online C 2011 standard, section 7.21.6.1, for the complete list of conversion specifiers.
printf doesn't automatically append a newline to all output the way System.out.println does - you have to specify it in the format string (\n).
Standard output is typically line buffered - output won't show up on the console until a) the buffer is full, b) the buffer is manually flushed with fflush, c) a newline appears in the buffer, or d) an input function (fgets, scanf, etc.) immediately follows the output function.
Array semantics in C and Java are wildly different. In C, arrays are not reference objects - they don't point to dynamically-allocated memory on the heap. However, the array subscript operation a[i] is defined in terms of pointer arithmetic - *(a + i). What happens in C is that when an array expression is not the operand of the sizeof or unary & operators, or isn't a string literal used to initialize an array in a declaration, the expression is converted ("decays") from type "N-element array of T" to "pointer to T", and the value of the expression is the address of the first element of the array.
This is a very long-winded way of saying that instead of writing
ch = &name1;
you should be writing
ch = name1;
instead. The expression name1 "decays" to a pointer to the first element of the array, and the resulting type of the expression is char *. The type of the expression &name1 is char (*)[256] (pointer to 256-element array of char), which is not what you want. They'll both evaluate to the same location (modulo any type conversions), but type matters.
Finally...
NEVER NEVER NEVER NEVER NEVER use gets. It will introduce a point of failure / major security hole in your code. It was deprecrated shortly after the release of the C99 standard, and has been officially removed from the standard library in C2011. That one library function has been responsible for untold amounts of mayhem over the decades. Do not use it, not even in toy code. It is the "Highlander II" of the C programming language - it never existed. Use fgets instead.