I'm getting runtime error in this program...why? - c

A program for merging two words:
#include<stdio.h>
int main()
{
char s1[10],s2[10],s3[10];
int i,j,n=1;
for(i=0;i<n;i++)
scanf("%s",&s1[i]);
for(i=0;i<n;i++)
scanf("%s",&s2[i]);
for(j=0;s2[i];j++)
{
s3[i] = s1[i]+s2[j];
}
printf("%s",s3);
return 0;
}
I'm getting a runtime error in this program. Could anyone help me to correct it or point out what the error is?

for(i=0;i<n;i++)
scanf("%s",&s1[i]);
for(i=0;i<n;i++)
scanf("%s",&s2[i]);
This is not how you read strings. Try this:
scanf("%s", s1);
scanf("%s", s2);
That's not perfect, but should work for a beginner.

scanf("%s",&s1[i]); does not do what you think it does. It seems to me you are confusing %s with %c. This is causing a buffer overflow. So read the documentation of scanf() format strings.
Then, don't use scanf() because it's unsafe and hard to use correctly. For getting user input, use fgets().

Your code have several problems:
You are using scanf in a wrong a way. It should be like scanf("%s", s1); same for s2.
To merge two strings you can use built-in function strcat which append its second argument to its first argument; just use it two times to merge your two strings in vector s3.
In conclusion, your code should look like:
#include<stdio.h>
#include <string.h>
int main()
{
char s1[10],s2[10],s3[20];
scanf("%s",s1);
scanf("%s",s2);
strcat(s3,s1);
strcat(s3,s2);
printf("%s",s3);
printf("\n");
return 0;
}
Just remember that your s3 vector must be sufficiently large to contain both your strings.

#include <stdio.h>
int main(void){
char s1[10], s2[10], s3[20];
int i, j, n=1;
scanf("%9s", s1);
scanf("%9s", s2);
sprintf(s3, "%s%s", s1, s2);
printf("%s\n",s3);
return 0;
}

You're probably doing a free online course "Programming, Data Structures & Algorithms" at https://onlinecourses.nptel.ac.in
Anyway, the answer to this is:
#include <stdio.h>
#include <string.h>
int main() {
char a[20], b[10], c;
int x[20];
int i,j,l,n,swap;
scanf("%s",a);
scanf("%s",b);
strcat(a,b);
l=strlen(a);
for(i=0; i<l; i++) {
n = a[i];
x[i] = n;
}
for(i=0; i<(l-1); i++) {
for(j=0; j<(l-i-1); j++) {
if(x[j]>x[j+1]) {
swap = x[j];
x[j] = x[j+1];
x[j+1] = swap;
}
}
}
for(i=0; i<l; i++) {
c = x[i];
printf("%c",c);
}
}

You should edit the question if you really meant this.
Okay first of all, if you declare like char arr[10]; then read like scanf("%s",arr);
So you read the two words like:
scanf("%s",s1);
scanf("%s",s2);
Okay, now to merge two words of length 10, first declare the result array to be twice of 10.
So here goes the full code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int compare (const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
int main()
{
char s1[10],s2[10],s3[20];
scanf("%s",s1);
scanf("%s",s2);
strcpy(s3,s1); // copies content of s1 to s3
strcat(s3,s2); // merges to end of s3 the content of s2
qsort(s3,strlen(s3),sizeof(char),compare); //sorts s3
printf("%s",s3);
return 0;
}
See qsort().

Related

scanf a string with size limit without ignoring spaces

i having problem scaning strings into a matrix that each string is maximum 256 long.
it tried this but it didnt work, someone have a solution?
#include<stdio.h>
#include<string.h>
void main()
{
char* song[5][256];
for (int i = 0; i < 5; i++)
scanf("%255[^\n]s", song[i]);
}
welcome to stackoverflow,
first of all i am not sure why you are using char *song[5][256],but you can achieve the required out by using a 2-dimentional array ie..char song[5][256].and also i am sure that using scanf function for a matrix like array will always cause a trouble.
#include<stdio.h>
int main()
{
char s[5][256];
for(int i=0;i<5;i++)
{
for(int j=0;j<256;j++)
{ char c=getchar();
if(c=='\n'||c== EOF)
{
s[i][j]='\0';
printf("\n");
break;
}
if(j<255)
s[i][j]=c;
if(j==255)
s[i][j]='\0';
}
printf("the given string %d is:%s \n",i+1,s[i]);
}
return 0;
}
And also i have used two for loops, for assigning the elements of that array.Now the code works fine.I used s insted of your variale name song.
Hope that I answered your question.

why the atoi function is not working?

The program stops working.
Even if I put only one int.
I tried many different ways but can't figure out what is wrong.
I am trying to take input of integers separated by space.
There can be any no of integers.
#include<stdio.h>
#include<stdlib.h>
int main(void) {
int i,j=0;
int b[100];
char a[100];
fgets(a,100,stdin);
for(i=0;i<strlen(a);i++)
{
b[i] = atoi(a[j]);
j=j+2;
}
for(i=0;i<strlen(b);i++)
{
printf("%d ",b[i]);
}
}
Here is the prototype of atoi you have to use a character array but you are sending a character only.atoi(str[i])
int atoi(const char *str)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int val;
char str[20];
strcpy(str, "98993489");
val = atoi(str);
printf("String value = %s, Int value = %d\n", str, val);
return(0);
}
Do the following:
for(i = 0; i < strlen(a); i += 2)
{
b[j] = a[i];
j++;
}
though atoi() accepts only a string argument or u can say constant char pointer and str[i] is nothing but a pointer pointing at a single character of the character array.
Therefore once we pass atoi(str[i]) , that means we are passing a character to the function, which will give an error.
Therefore you must pass the address of that particular character from where you want to convert the substring into a number i.e. atoi(&str[i]).

Integer from pointer warning

I have I problem. I get 2 warnings from console, but I dont know what's wrong with my code. Can you have look?
Program suppose to show lines with at least 11 characters and 4 numbers
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
if(isalpha(line)) numberAlpha++;
else if(isdigit(line)) numberDigit++;
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Both isalpha() and isdigit() takes an int, not a char *, as argument.
In your code, by passing the array name as the argument, you're essentially passing a char * (array name decays to the pointer to the first element when used as function argument), so, you're getting the warning.
You need to loop over the individual elements of line and pass them to the functions.
That said, just a suggestion, for hosted environment, int main() should be int main(void) to conform to the standard.
isalpha and isdigit are supposed to test if a char taken as int (a char can be safely converted to an int) is the encoding of an alphanumeric or digit character. You pass a char array, not an individual char. You need to test each char of the string you got, so you need a loop as:
for (int i=0; i<strlen(line); i++) {
if (isalpha(line[i])) numberAlpha++;
...
}
It is better to compute the length once:
int length = strlen(line);
for (int i=0; i<length; i++) {
...
}
You may also use a pointer to move along the string:
for (char *ptr = line; *ptr!=`\0`; ptr++) {
if (isalpha(*ptr)) ...
...
}
isalpha() and isdigit() functions take an int. But you are passing a char* i.e. the array line gets converted into a pointer to its first element (see: What is array decaying?). That's what the compiler complains about. You need to loop over line to find the number of digits and alphabets in it.
Also note that fgets() will read in the newline character if line has space. So, you need to trim it out before counting.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
line[strcspn(line, "\n")] = 0; // Remove the trailing newline, if any.
for (size_t i = 0; line[i]; i++) {
if(isalpha((unsigned char)line[i])) numberAlpha++;
else if((unsigned char)isdigit(line[i])) numberDigit++;
}
printf("alpha: %d, digits:%d \n", numberAlpha, numberDigit);
}
return 0;
}
Ok, i got something like this:
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
int i;
for(i=0; i<strlen(line); i++){
if(isalpha(line[i])) numberAlpha++;
else if(isdigit(line[i])) numberDigit++;
}
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Now the question is, if it is passible to make it first accepts data and then display only those line which follows the if statment. Now it shows line just after input it.

Anagram project

I am having trouble trying to get the "isZero" function to detect if the word is an anagram or not. Asking if "isZero" is equal to 1 in main() it will only give me "anagram". And if i set it to 0 it will only give me "not anagram". To me it is not computing anything, it is just printing out whatever statement is true at the moment. Not sure how to solve this and could use some guidance.
#include <stdio.h>
#include <ctype.h>
#define MAX 26
void intialize(char a[], char b[], int c[]);
void setLetters(char newCount[], int newNumber[]);
void checkLetters(char b[], int newNumber[]);
int isZero(int c[]);
void getstring(char a[]);
void getString(char b[]);
int main(void)
{
char a[MAX], b[MAX];
int c[MAX];
intialize( a, b, c);
getstring(a);
getString(b);
setLetters(a, c);
checkLetters(b, c);
if (isZero(c) == 1) {
printf("anagram");
} else
printf("not anagram");
return 0;
}
void intialize(char a[], char b[], int c[])
{
int i;
for(i = 0; i < MAX; ++i) {
a[i] = '\0';
b[i] = '\0';
c[i] = 0;
}
}
void setLetters(char newCount[], int newNumber[])
{
int i, index = 0;
for(i = 0; i < MAX; ++i) {
if(isalpha(newCount[i])) {
newCount[i] = tolower(newCount[i]);
index = (int)(newCount[i] - 'a');
newNumber[index] +=1;
}
}
}
void checkLetters(char b[], int newNumber[])
{
int i, index;
for(i = 0; i < MAX; ++i) {
if(isalpha(newNumber[i])) {
newNumber[i] = tolower(newNumber[i]);
index = (int)(newNumber[i] - 'a');
newNumber[index] -= 1;
}
}
}
int isZero(int c[])
{
int i, j = 0;
for(i = 0; i < MAX; ++i) {
if(c[i] == 0)
j = 1;
else
return 0;
}
return j;
}
void getstring(char a[])
{
char line[MAX];
printf("Enter a string: ");
gets(line);
}
void getString(char b[])
{
char line[MAX];
printf("Enter a string: ");
gets(line);
}
With C it is mandatory that you slow down and understand what each part of each line does. There is no part of C where close enough is correct. That being said, you had an overall idea about how to approach the problem. However, it was very clear that you are just starting out in C (given the other answers and comments).
Before you start writing functions, determine what you need a function to do. Then try and determine how best to handle that task. If you need a function to get string input, then write one to do that. If you find yourself having to write one function to fill each string stop, your have just defeated the purpose of the function. Writing a function to do the same thing for a[] and another identical function for b[] makes no sense. You don't need a function to loop through all arrays setting your newly declared arrays to zero/NULL, that's what array initialization syntax is for.
Before you expect to have functions work, take the time to learn how to pass values to (and if a return is needed -- get values from) a function. When you pass an array to a function, pointer decay occurs. That means array a[] decays to *a when passed to a function. You can take advantage of this by declaring your functions to accept *a as the argument. While this isn't earth-shattering for a simple 1-D array, the decay becomes more involved with 2-D arrays and above.
In addition to figuring out which code makes sense as a function, you need to be just as exact with your logic in C as you are with its syntax. If there is any part of a line your are unsure about, look it up, look at the man page for the function you are using, or consult a language reference for your compiler (Gnu/MS), etc. to make sure you know exactly what your code does. It will save you time in the long run. The number one thing that trips new C programmers up, is trying to skim the manual or skim the book and then start writing code. The key to learning C is to just slow down.
Never, Never, Never use gets(). If you are taking a class and the teacher hands you an assignment using it, go to administration and ask for a refund. gets() is no longer part of the standard C library due to how easily it is compromised and exploited. Use fgets, getline, or scanf (read the entire section on proper use of the scanf format string if you chose to use it). It is a fine function, but it has many, many pitfalls just waiting for someone that partially understands its use.
That being said, you had the overall logic for one approach to anagrams. Below I've provided an example of the points above in sorting out your code. Take the time to read through it and understand why I made the changes I did. Additionally, I added a quick length check for the words input. If they are not the same length, no need to go further. Let me know if you have questions. There are a lot of good folks here that are happy to help.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 26
void setLetters(char *newCount, int *newNumber);
void checkLetters(char *newCount, int *newNumber);
int isZero (int *c);
void getstring (char *a);
int main (void)
{
char a[MAX] = {0}; /* initialize all to zero/NULL */
char b[MAX] = {0};
int c[MAX] = {0};
getstring(a);
getstring(b);
printf ("\n You entered:\n\n a: %s\n b: %s\n\n", a, b);
/* test lengths - if differ, not anagram */
if (strlen(a) != strlen(b)) {
printf (" Lenghts differ, cannot be an anagram.\n\n");
return 1;
}
setLetters (a, c); /* set key array (c) */
checkLetters (b, c); /* check key array (c) */
if (isZero(c))
printf(" The words form an anagram.\n\n");
else
printf(" The words are not and anagram.\n\n");
return 0;
}
void setLetters (char *newCount, int *newNumber)
{
int i = 0;
int index = 0;
for (i = 0; i < MAX; ++i) {
if (isalpha (newCount[i])) {
newCount[i] = tolower (newCount[i]);
index = (int)(newCount[i] - 'a');
newNumber[index] +=1;
}
}
}
void checkLetters(char *newCount, int *newNumber)
{
int i = 0;
int index = 0;
for (i = 0; i < MAX; ++i) {
if (isalpha (newCount[i])) {
newCount[i] = tolower (newCount[i]);
index = (int)(newCount[i] - 'a');
newNumber[index] -= 1;
}
}
}
int isZero (int *c)
{
int i = 0;
for (i = 0; i < MAX; ++i)
if (c[i] == 1)
return 0;
return 1;
}
void getstring (char *a)
{
printf ("\n Enter a string: ");
scanf ("%[^\n]%*c", a);
}
output:
$ ./bin/anaproj
Enter a string: yekcim
Enter a string: mickey
You entered:
a: yekcim
b: mickey
The words form an anagram.
$ ./bin/anaproj
Enter a string: yekcim
Enter a string: mickez
You entered:
a: yekcim
b: mickez
The words are not and anagram.
void getstring(char a[]);
This API is not doing what you intend to do.
This has a local variable line and your are reading a string to it and the char array in main() i.e. a is never been filled up with anything.
You continue to use the char array a thinking the values are filled in it by calling getstring() which is not happening. You need to fix this first and later work on the algorithm for anagram.
There is something called pass by reference which might help you.

Problems with simple c task

So after a few years of inactivity after studying at uni, I'm trying to build up my c experience with a simple string reverser.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
reverser();
return(0);
}
int reverser(){
printf("Please enter a String: ");
//return (0);
int len;
char input[10];
scanf("%s",&input);
int quit = strcmp(input,"quit");
if(quit == 0){
printf("%s\n","Program quitting");
return(0);
}
len = strlen(input);
printf("%i\n",len);
char reversed[len];
int count = 0;
while (count <= (len-1)){
//printf("%i\n",(len-count));
reversed[count] = input[(len-1)-count];
count++;
}
//printf("%s\n",input);
printf(reversed);
printf("\n");
reverser();
}
When I input "hello", you would expect "olleh" as the response, but I get "olleh:$a ca&#",
How do I just get the string input reversed and returned?
Bombalur
Add a '\0' at the end of the array. (as in, copy only chars until you reach '\0' - which is the point at array[strlen(array)], then when you're done, add a '\0' at the next character)
Strings are conventionally terminated by a zero byte. So it should be
char reversed[len+1];
And you should clear the last byte
reversed[len] = (char)0;
you forgot the \0 at the end of the string
This is because you are creating an array with size 10. When you take in some data into it (using scanf) and the array is not filled up completely, the printf from this array will give junk values in the memory. You should iterate for the length of the input by checking \n.
must have a size + 1 to string length so that you can have a \0 at the end of string that will solve your problem
The following is a (simple and minimal implementation of) string reverse program (obviously, error conditions, corner cases, blank spaces, wider character sets, etc has not been considered).
#include <stdio.h>
int strlen(char *s)
{
char *p = s;
while (*p)
p++;
return p - s;
}
char * strrev(char a[])
{
int i, j;
char temp;
for (i=0, j=strlen(a)-1 ; i<j ; i++, j--) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
int main()
{
char str[100];
printf("Enter string: ");
scanf("%s", str);
printf("The reverse is %s \n", strrev(str));
return 0;
}
Hope this helps!

Resources