I want my program to prompt the user for how many sentences they want to write and then enter those sentences. However, when I try entering the sentences, I keep getting errors. I tried using several different fucntions but all of them gave some kind of error. For example, right now I am trying to use fgets() and after I enter the first sentence it gives me a segmentation fault. Can someone tell me what is the best way to take input for a string with spaces and how to fix my problem?
int n;
char str[n][80];
printf("Enter number of lines: ");
scanf("%d", &n);
printf("Enter a sentecne: ");
for(int i = 0; i < n; i++){
fgets(str[i], 80, stdin);
printf("%s", str[i]);
}
You define the array str before you initialize n. That means n will have an indeterminate value (which will be seemingly random).
Move the input of n to before you define str.
you can use read function http://man7.org/linux/man-pages/man2/read.2.html
reading on the file descriptor 0 (standart input), a char *buffer to store your data, and a size_t size to read
there are several problems in your code
int n; // must have a value
int n = 10; // example, here your variable is initialized
you also don't check the return value of scanf
Related
The assignment asks to print out the number of times a chosen character appears in an input (no length limit) string. I wanted to solve it by only using do or do-while loops, and after a bit of googling I found this code (source: https://www.tutorialgateway.org/c-program-to-count-all-occurrence-of-a-character-in-a-string/.).
I get the gist of it, but there are many things I still haven't covered, such as the meaning of str[i], the meaning of the variable ch, and kind of how the structure works. How can I interpret it piece by piece? Or if there's any simpler way, how can I work on it? I'm a beginner and I fear this is much easier than expected but I don't have the base to move on, thank you
#include <stdio.h>
#include <string.h>
int main() {
char str[10], ch;
int i, Count;
i = Count = 0;
printf("\n Please Enter any String : ");
gets(str);
printf("\n Please Enter the Character that you want to Search for : ");
scanf("%c", &ch);
while (str[i] != '\0') {
if (str[i] == ch) {
Count++;
}
i++;
}
printf("\n The Total Number of times '%c' has Occurred = %d ", ch, Count);
return 0;
}
Well i am giving an easy example regarding that problem with a proper explanation. Hope you might understand.
char is a datatype which will accepts character type of variable. Here str[100] will be an array of length 100, where we will store our search example. ch is a character type variable where we will store the character for which we will find the concurrence.
i and count are integer variables where i will be loop variable and the count will keep count of the concurrence.
after taking the text string using puts function we are storing it in the str[100] array.
then we are taking the search letter and stored it in ch.
we are now running for loop from 0 to the length of the string we have given.
strlen() function returning us the length.
now str[i] will search from i=0 to the length size of the string. each time loop will go forward one by one letter and compare the letter with the letter inside ch.
if match found then we will increase the count value.
after the ending of the loop count will be the result of the concurrency.
reference: Concurrency of a letter in a string
#include <stdio.h>
#include <string.h>
int main()
{
char str[100], ch;
int i, Count;
Count = 0;
printf("\n Please Enter any String : ");
gets(str);
printf("\n Please Enter the Character that you want to Search for : ");
scanf("%c", &ch);
for(i = 0; i <= strlen(str); i++)
{
if(str[i] == ch)
{
Count++;
}
}
printf("\n The Total Number of times '%c' has Occured = %d ", ch, Count);
return 0;
}
The code has the following parts:
1)The header files: These contain predefined functions like scanf() which you use in your program
2)The main function: Here you are performing your character count. Usually, this function contains the driver code for the program
ch is a variable for the character you want to count in your string. You are taking this as input from the user using scanf()
str is the string you are performing your count operation in. It is also taken as input.
str[i] is used to denote the index i in the string. For example in "test", the index of 's' will be 2 as it is the 3rd character and your index starts from 0.
Final note: I recommend going through the basic syntax and usage of arrays if you do not know indexing. Also, as someone commented, do not use gets(). It causes security issues in programs as user can access stack values by giving malicious inputs containing format specifiers.
Instead, use a scanf with proper format specifiers or use fgets() when accessing content from files.
I'm trying to make a program that writes to a file every combination of letters formed from a given phone number. I'm fairly positive it's giving the segfault where I scanf the name of the file the user wants to write to (in main) because I've put in printf tests and they don't print. For some reason, before adding in my recursive functions it doesn't give me a segfault but after adding them it does.
const char letters[8][5] = {"ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};
int main()
{
int userNum[7];
char userFile[25];
printf("Please enter the phone number you want to process with no added
characters or spaces: ");
scanf("%d", &userNum);
printf("Enter the file name (including extension and less than 25
characters) that you would like to write to.\n");
scanf("%s", userFile); //This is where I think the seg fault is happening
printf("Test"); //Because this doesn't print
FILE* file_ptr;
char fileName[17];
sprintf(fileName, "%s", userFile);
file_ptr = fopen(fileName, "w");
findWordsHelper(userNum, 7);
}
//Adding this function and the one after is what made the program start
//giving said seg fault
void findWords(int userNum[], int digit, char words[], int n)
{
printf("Test. n = %d", n);
int i;
if(digit == n)
{
printf("%s ", words);
return;
}
for(i = 0; i < strlen(letters[userNum[digit]]); i++)
{
words[digit] = letters[userNum[digit]][i];
findWords(userNum, digit+1, words, n);
if(userNum[digit] == 0 || userNum[digit] == 1)
{
return;
}
}
}
void findWordsHelper(int userNum[], int n)
{
printf("test");
char result[n+1];
result[n] = '\0';
findWords(userNum, 0, result, n);
}
I'm not in an environment that I can test but I see a few things. First off, your printf test isn't printing because if has no new line character. If you're not going to put one in, call fflush. E.g
printf("test");
fflush(stdout);
Second, your use of scanf to read in the phone number shows a bit of misunderstanding of how scanf will treat input as an integer. You don't need an array of 7 ints for this because you've simply instructed for the input to be no extra characters. So, a phone number like 345-6789 is input as 3456789 which will be read as a single int: i.e 3 million, 4 hundred 56 thousand, 7 hundred 89. This will be read into a single integer. I know you want to treat them as separate numbers, but scanf will treat them as 1 number when not separated by whitespace. To read into a single int, this would suffice:
...
int phoneNumber;
scanf("%d", &phoneNumber); // <--- notice the & operator
EDIT
I was reading over the manual page for scanf() and when the %s specifier is used, it should insert a null-character into the string. So, the part directing to check the return and ensure a '\0' character is placed there is not applicable.
EDIT 2
I had a moment this morning and had to figure this out. I think I've got it. Something in the function findWords() looked a bit suspect and compiling, seg-faulting, and looking at the core file showed it to be the case. It's this line in that function
for(i = 0; i < strlen(letters[userNum[digit]]); i++)
Specifically, it is the call to strlen() with the result of using userNum[] to index into letters[]. As myself, and others, have indicated, scanf() isn't going to read a "phone number" such as 3456789 (input as such) into 7 different integer values. It is read as a single int and it's going to be read into userNum[0] (and guess what? digit = 0 when the segfault occurs). This is no surprise, the letters array does not contain 3 million, 4 hundred 56 thousand, 7 hundred 89 indecies. (Assuming the number entered is what I wrote.)
As mentioned by Jasen (I think), ints don't really work well for phone numbers. At the very least, you'll have to develop a different manner of breaking apart the phone number to use as an index.
First of all, lack of printf output does not indicate that the program did not execute past that point, as the output is probably buffered.
You can either do fflush(stdout) immediately after a printf call, or use setvbuf with a null argument to force unbuffering.
Second, in your recursive function, each call results in calling itself up to the number of iterations in your for loop. I suspect there are logic errors there and the number of recursive calls may just explode.
Third, you definitely have a logic problem here:
int userNum[7];
...
scanf("%d", &userNum);
Looks like you are expecting that if a user enters "1234567", that each userNum[i] contains one of the digit, but that's not what's happening.
scanf would treat the argument as a pointer to an int, e.g. on a 32-bit CPU, it would put the integer value 1234567 into the first 4 bytes of "userNum". In fact, this could cause a segfault right there if the CPU cannot write to an integer (whether 16 or 32 bits) to an unaligned address. As userNum is actually an array, it may or may not be aligned suitable for an integer.
int main() {
int userNum[7];
char userFile[25];
printf("Please enter the phone number you want to process with no added"
" characters or spaces: ");
printf("Enter the file name (including extension and less than 25 "
" characters) that you would like to write to.\n");
scanf("%s", userFile); //This is where I think the seg fault is happening
should be :
scanf("%24s",userfile);
that puts a limit of 24 chars on what is read.
char fileName[17];
sprintf(fileName, "%s", userFile);
However userfile could be 24 long... and that can only fit 16, so it should be.
sprintf(fileName, "%.16s", userFile);
which chops off any overflow.
This is a simple program in which the user enters a series of numbers which are then added. The result is printed on the screen. Here's the code:
int main() {
int * numbers;
int result = 0;
int howMany;
int i;
printf("How many numbers would you like to add?\n");
scanf(" %d\n", &howMany);
numbers = (int *) malloc(howMany * sizeof(int));
for(i = 0; i < howMany; i++){
printf("Please enter number %d.\n", i + 1);
scanf(" %d\n", &numbers[i]);
result = result + numbers [i];
}
printf("Result: %d", result);
return 0;
}
But there is a problem. The program asks for how many numbers the user would like to add twice for some reason. Why is that? How can I fix it?
Also, not sure if this is related but the results also make no sense. Sometimes they are correct, other times they aren't, not sure why either.
Thanks.
The program asks for how many numbers the user would like to add twice for some reason. Why is that? How can I fix it?
Your program prompts me only once for how many numbers. It does, however, defer asking for each specific number until after I enter it, and then it requires an extra non-blank line after the last (late) prompt before it outputs the result.
Also, not sure if this is related but the results also make no sense. Sometimes they are correct, other times they aren't, not sure why either.
It is related: the fact that the per-number prompts are late is confusing you about which numbers are being added.
This all comes down to your scanf() formats, as #Mark already remarked (albeit somewhat tersely). Any nonempty run of whitespace, including newlines, in a scanf() format matches a possibly-empty run of whitespace. When it is matching such a run, scanf() has to keep scanning until it sees a non-whitespace character. Interactive input is line-buffered, however, so no new input is available to it until you send a whole new line. Then the first non-whitespace character on that next line is ready and waiting for the following scanf().
scanf() can be quite tricky to use correctly, especially for interactive input. It is best suited for fixed-format input. You can do this with scanf() -- #Mark showed you how -- but the usual recommendation around here is to use fgets() to read input one line at a time, and sscanf() (or your choice of other mechanism) to parse each line. Even that can be a challenge to make bullet-proof, but you start out on firmer footing.
Your problem was because of your erroneous placement of the newline characters in your printf and scanf functions.
Here is the code you are probably looking for:
int main() {
int * numbers;
int result = 0;
int howMany;
int i;
printf("How many numbers would you like to add?: ");
scanf("%d", &howMany);
numbers = (int *) malloc(howMany * sizeof(int));
for(i = 0; i < howMany; i++){
printf("Please enter number %d: ", i + 1);
scanf("%d", &numbers[i]);
result = result + numbers [i];
}
printf("Result: %d\n", result);
return 0;
}
I have a small program, where i say the number of lines and columns of a array I want to input, then input info to fill that array with data. What it does next it's not important so ill just omit that part of the code and put (...) in it.
int main (){
int nl, nc,i,j,z,n;
scanf ("%d %d\n", &nl,&nc);
char matrix [nl] [nc];
for (i=0;i<nl;i++)
for (j=0;j<nc;j++)
scanf(" %c",&matrix[i][j]);
scanf("%d",&n);
int s[n*2];
for (z=0;z<n*2;z++)
scanf("%d",&s[z]);
int y=0;
char s2[n];
for (z=0;z<n*2;z+=2){
s2[y]=matrix [(s[z])-1][(s[z+1])-1];
y++;
}
for (z=0;z<n;z++)
printf ("%c", s2[z]);
return 0;
}
My problem is, that it this blows up if input more chars than I should. For example if my input is:
2 3
ABC
DEF
This works just fine.
But if I put:
2 3
ABC
DEFF
It give me a segmentation fold and stops the program. Keep in mind that I have a space before the "%c" in scanf so it's ignoring the "\n" and spaces I put in the input.
What can I do to stop that extra chars in the array from blowing up?
scanf("%d",&n);
int s[n*2];
This code tries to scan and convert whatever is left in the input after reading the matrix. If the input is not numeric, as will be the case if you enter more letters than the matrix should contain, the conversion will fail and n will remain uninitialized. Then int s[n*2]; is undefined because n is indeterminate.
If you want to ignore some characters in the input, you need to do so explicitly. You also better check return values of all functions that take user input, and verify that the values read are sensible.
Ok i figured out that the problem with it was input going to the buffer. To solve this i cleared the buffer before the next input using:
while (getchar() != '\n');
Your problem is filling the array over that size.
You get your input character by character and if you enter character more than your array size the program will stopped or has been logical error,
So you can use getche() and check the array constraint.
You can edit your code as follow:
int main (){
int nl, nc,i,j;
scanf ("%d %d\n", &nl,&nc);
char matrix [nl] [nc];
for (i=0;i<nl;i++)
for (j=0;j<nc;j++)
matrix[i][j]=getche();
(...)
return 0;
}
Use %s instead of %c and remove the inner loop. So the code will be something like this:
for(i=0; i<nl; i++)
{
scanf("%s", &matrix[i]);
}
I have the following code which stores string-input from a user N times in a multidimensional array. And then print out the second element.
main()
{
// Array to store 10 strings, 20 characters long.
char strStorage[10][20];
printf("\nEnter how many strings: ");
scanf( "%d" , &num);
fflush(stdin);
for ( count = 0 ; count < num ; count++)
{
printf("Enter a string: ");
gets(strStorage[count]);
fflush(stdin);
}
printf("%s", strStorage[2]);
Last line prints out garbage. The user-input is not visible inside the garbage hence either my element access is wrong or my storage is wrong. Can anyone help me with regards to what is the problem?
Thanks in advance...
strStorage[2] is the third string, so if num is less than 3, you won't initialize it and it will contain garbage.
scanf("%d", &num); doesn't ensure that num contains a value. Perhaps it'd be wise to check the return value of scanf to ensure it read 1 value, like this: if (scanf("%d", &num) != 1) { puts("Error reading integer"); }
While we're on this topic, I presume num and count are declared as an int, and you've hidden the declarations from us. Tsssk! Do you want our help? If so, then make your code compilable! Do you really think int is suitable for storing indexes to arrays? It's possible that they might have negative values. I'd suggest using size_t, instead, and the %zu format specifier tells scanf to expect a size_t value from stdin.
... and what happens when that size_t contains a value greater than the number of elements in your array? I suggest researching variable length arrays.
fflush(stdin); is nonsense because fflush defines behaviour for files open for output, and stdin is a file open for input only. That's sort of like flushing the toilet and expecting the waste to come out of the bowl, rather than going down through the S-bend. Perhaps you mean to discard the remainder of a line, because you've read the data you need from the start of it. Something like for (int c = getchar(); c >= 0 && c != '\n'; c = getchar()); might work.
Don't use gets. Use fgets(strStorage[count], sizeof strStorage[count], stdin); instead, to ensure that no buffer overflows occur.
There, I think I covered just about every bit of undefined behaviour and nit-picky stuffs.