comparing two strings sectioned into different parameters in C - c

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.

Related

How on earth to use char and if statements?

I'm a rookie programmer trying to run a simple code on VS code.
#include<stdio.h>
int main()
{
char* a;
printf("Enter a char");
scanf("%s",&a);
if (a = "yes")
{
printf("Number is 30");
}
else if (a = "no")
{
printf("Number is 50");
}
else{
printf("oops");
}
return 0;
}
I guess looking at the code you guys can figure out what I'm trying to do, if the user enters "yes", a specific sentence need to be displayed and similarly for "no".
The problem here is whatever I write in the input, it will always print the first statement, "Number is 30". I've tried running similar codes but ended up with the same output.
If possible, please explain me how to use char,strings,arrays with if-else statements.
There are several misunderstandings in the posted code.
First there is a misunderstanding of char versus string. A char is for instance a single letter, a single special character like ., ;, etc. (see note1) while a string is a serie of chars. So
'y' is a char
"yes" is a string
You print "Enter a char" but from the code it's obvious that you really want "Enter a string".
This leads to the next problem. To input a string using scanf you need to pass a "pointer to char". Your code pass "a pointer to pointer to char" due to the &. Further the passed pointer must point to some memory. So you need:
char a[10]; // Make it an array of char so that it can hold a string
printf("Enter a string, max 9 characters");
scanf("%9s", a); // No & before a and width specifier used to avoid buffer overflow
Now this part
if (a = "yes")
is not the way to compare two strings in C. For that you need the function strcmp - like:
if (strcmp(a, "yes") == 0)
Putting it together it's like:
int main()
{
char a[10];
printf("Enter a string, max 9 characters");
scanf("%9s", a);
if (strcmp(a, "yes") == 0){
printf("Number is 30");
}
else if (strcmp(a, "no") == 0)
{
printf("Number is 50");
}
else
{
printf("oops");
}
return 0;
}
That said, I don't understand why you print stuff like: "Number is 30" but that's kind of irrelevant here.
note1: The type char is actually an integer type, i.e. a number, but the common use is to map these numbers to characters using ASCII encoding.
There are different ways to initialize a variable to access C string.
char *char_ptr = "Hello";
This initializes char_ptr to point to the first character of the read-only string "Look Here".A C string initialized through a character pointer cannot be modified. When a C string is initialized this way, trying to modify any character pointed to by char_ptr is undefined behaviour. An undefined behaviour means that when a compiler encounters anything that triggers undefined behaviour, it is allowed to do anything it seems appropriate.
A more convenient way to define strings that can be modified is to use:
char str[];
This way you can modify any character in the C string
p.s you also need to use strcmp() for the if statement
You can take string input in C using
scanf(“%s”, str);
And to compare the string you need to use:
strcmp(str1, "yes");

C Programming - Trouble with pointers, no console output

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.

'Scanf' for a String - Program crashing?

Why is this crashing when I input the string? I don't think I'm reading in the string right but the program gives me an error on the first 'scanf.' The program should be correct but this is C not C++. Most help that I could find was for C++.
//Andrei Shulgach
//April 27th, 2015
/*A string is a palindrome if it can be read forward and backward with the same
meaning. Capitalizations and spacing are ignored.*/
#include <stdio.h>
#include <stdlib.h>
int newStrCmp (const char *string1, const char *string2);
int main()
{
//Local Declarations
int dummy, value;
char string1[100],string2[100];
printf("Please enter the 1st string: ");
scanf_s("%99s", string1[100]);
printf("\nPlease enter the 2nd string: ");
scanf_s("%99s", string2[100]);
//Call Function and get value
value = newStrCmp(string1, string2);
if (value == 0)
printf("The strings are equal.\n");
else
printf("The strings are not equal.\n");
scanf_s("%d",&dummy);//Keep Window Open
return 0;
}
int newStrCmp (const char *string1, const char *string2)
{
//Local Declarations
int value = 0;
while (string1[value] == string2[value])
{
if (string1[value] == '\0' || string2[value] == '\0')
break;
value++;
}
if (string1[value] == '\0' && string2[value] == '\0')
return 0;
else
return -1;
}
You must enable all compiler warnings that you can get from your compiler; the above code shouldn't have compiled.
This:
scanf_s("%99s", string1[100]);
invokes undefined behavior since it indexes outside the 100-character string1 array. Remember that C arrays are indexed from 0. It also fails to comply with scanf_s()'s requirement that the size be specified for all string conversions.
It then probably1 causes more undefined behavior, when scanf_f() interprets a single character as a buffer address where input is to be stored (assuming the call happens, of course).
This is not valid code.
It should simply pass the address of the first character in the array:
scanf_s("%99s", string1, sizeof string1);
Here, string1 is the same as &string1[0]; the name of an array evaluates to the address of its first element in many contexts. We then use sizeof string1 as the third argument to specify the size of the string1 buffer, which is required.
1 You cannot reason about what happens after undefined behavior has happened with any certainty.
The issue is you are 'scanf'ing into index 100 of your length 100 buffer, i.e. out-of-bounds.
scanf_s("%99s", string1);
Also your comparison would be safer as a for loop that ensures value is less than 100, rather than a while loop.
In the future, please include the error message.

What happens when using scanf("%d", &c) while c is a char?

the code is like this:
char c;
scanf("%d", &c);
inputting 3...
My guess is that when 3 is inputted, it is as type int;
and then type-demoted to char and assigned to c;
I print the value of c in specifier %d yielding 3, seems to be as expected;
but printing the value of c with specifier %c yields --a blank-- on the terminal;this is one question...(1);
to test more I furthermore declare a variable ch with type char and initialized it like this:
char ch = 1;
and the test is like this:
(i&j)? printf("yes") : printf("no");
and the result is "no"
I print out the value of i&j, and it is 0
but 1&3 should be 1? this is another question....(2);
my question is (1) and (2)
You're actually invoking undefined behavior doing that.
By using the format string %d, you're telling scanf to expect an int* as a parameter and you're passing it a pointer to a single character. Remember that scanf has no further type information on what you're passing it than what you're putting in the format string.
This will result in scanf attempting to write an int sized value to memory at an address that points to a char sized reservation, potentially (and for most architectures) writing out of bounds.
After invoking UB, all bets are off on your further calculations.
Suppose that scanf() were not a varargs-function, but a plain ordinary function taking a pointer-to-int as the 2nd argument:
int noscanf(char *format, int *ptr)
{
*ptr = 42;
return 1;
}
int main(void)
{
char ch;
int rc;
// This should *at least* give a warning ...
rc = noscanf("Haha!" , &ch);
return 0;
}
Now, scanf() is a varargs function. The only way for scanf() to determine the type of the (pointer) arguments is by inspecting the format string. And a %d means : the next argument is supposed to be a pointer to int. So scanf can happily write sizeof(int) bytes to *ptr.
I can't see a variable jthere. So i&j will be 0. And yes, if i == 1 and j == 3 then i & j == 1.
(i&j)? printf("yes") : printf("no");
statement gives the output yes,for i=1 and j=3.
And for (1) question ASCII 3 is for STX char which is not printable.

Passing Variables through functions C

Hello im just beginning to learn C and i want to know why im getting a problem here..
i wish to pass a char pointer
char *temp;
into a function ie call to function
checkIfUniqueCourseNo(temp,k);
with a prototype
int checkIfUniqueCourseNo(char checkchar[4],int);
and a function header
int checkIfUniqueCourseNo(char checkchar[4], int k)
Im sure im doing something really stupid here but im not sure how to fix it :(
thanks in advance. ps my error is that checkchar[4] outputs a P...
Example---
temp = "123A"
checkIfUniqueCourseNo(temp,k);
int checkIfUniqueCourseNo(char checkchar[4], int k){
printf("CheckifUniqueCourse\n");
printf("Check Value = %c \n", checkchar);
return 0;
}
Output = Check Value = P
temp = "123A"
checkIfUniqueCourseNo(temp,k);
int checkIfUniqueCourseNo(char checkchar[4], int k){
printf("CheckifUniqueCourse\n");
printf("Check Value = %c \n", checkchar);
^^^^^^^^^
return 0;
}
If you're trying to print out the first character of checkchar, then you need to change this line to either
printf("Check Value = %c\n", *checkchar);
or
printf("Check Value = %c\n", checkchar[0]);
In the context of a function parameter declaration, T a[N] and T a[] are equivalent to T *a; a is declared as a pointer to T, not an array of T.
When you wrote
printf("Check Value = %c\n", checkchar);
you lied to printf; you said the argument is supposed to be of type char, but you passed a char *. Hence the bogus output.
If you want to print out the entire string "1234", then you need to change that line to
printf("Check value = %s\n", checkchar);
This time we use the %s conversion specifier to tell printf that checkchar points to a 0-terminated array of char (a.k.a. a string).
This is not at all clear. Are you assigning any value to temp? If so, what?
It would make more sense to have your prototype as:
int checkIfUniqueCourseNo(char* checkchar, int);
Since it's not at all clear where you got the 4 from.
It's been a while since I've done C, but I can see a few problems here, temp = "123A" actually requires an array for 5 characters (one of which is to include the '\0' string terminating character).
Secondly, the line printf("Check Value = %c \n", checkchar); seems to be trying to print a memory pointer as a character, change it to the following: printf("Check Value = %s \n", checkchar); and it will output each character in the array until it hits the terminating character.
There are a couple of things to look at here, you need to take a good look at the data you have, how it is represented and what you want to do with it.
Your course code appears to be a four character string, you should know that traditionally, strings in C also include an extra byte at the end with the value of zero (NUL) so that the many string functions that exist know that they have reached the end of the string.
In your case, your four digit code takes up five bytes of memory. So wont fit well passing it into your function.
If I were you, I would pass in a pointer like so:-
int checkIfUniqueCourseNo(char* coursecode, int k ) {
int rv = -1;
if ( coursecode == NULL ) return rv;
//...
I have no idea what K is for, do you?
Once you have your sequence of bytes inside your function you can save yourself alot of hastle later by doing some simple bounds checking on the data like so:
//...
if ( strlen(coursecode) > 4 ){
fprintf(stderr,"course code too long\n");
return rv;
}
if ( strlen(coursecode) < 4 ){
fprintf(stderr,"course code too short\n");
return rv;
}
//...
You can be sure you have a 4 character string now..

Resources