Character Arrays using - c

I want to use scanf_s("%c\n", &arr[index]) to input once character at a time in a single line using for/while loop. I cannot figure out how to output the result. Below is the code.(I only want to use scanf statement. fgets way is easy.
printf("\nEnter the lowercase letters\n");
for (index = 0; index < size; index++)
{
scanf_s("%c\n", &arr[index]);
_getch();
}
printf("\nThanks");
for (index = 0; index < size; ++index)
{
printf("%c/n", arr[index]);
}
It takes the input but exits out after thanks statement. I cannot figure out why. Although I have used a different method that works. It's just a variation I was trying.

Change
scanf_s("%c\n", &arr[index]);
_getch();
To
scanf_s(" %c", &arr[index], 1);
When scanning a character(%c) or string(%s) using scanf_s, you must supply an additional value as a parameter which indicates the amount of characters to be scanned.
The space before %c discards all whitespace characters(newlines, spaces etc) including none before scanning a non-whitespace character.
Also, the printf in the loop has /n instead of \n for a newline.

This code would probably work better:
int nchars;
printf("\nEnter the lowercase letters\n");
for (index = 0; index < size; index++)
{
if (scanf_s("%c", &arr[index], 1) != 1)
break;
}
printf("\nThanks\n");
nchars = index; // Do not report on values that were not entered
for (index = 0; index < nchars; ++index)
{
printf("%c\n", arr[index]);
}
Note that when you use scanf_s() and the %c format (and %s and %[…]formats), it require a length as well as the pointer to the data storage location (two arguments for one conversion specification). This tells the function how much space there is available to store the value. Often, the length will not be 1; you'd use scanf_s("%s", buffer, sizeof(buffer)) to read a string.
It is a good idea to check the return value from scanf_s() every time you use it so that you know whether it worked or not.
You can add extra criteria for breaking the loop, such as if the code reads a newline.
I also noted some problems in the comments — the issues are fixed in the code above.
Why are you using _getch() when you're also scanning with scanf_s()? That's going to confuse the poor user who types abcd and sees only ac. The _getch() is eating the b and d.
Also, newline is \n not /n — the third printf() has that as a typo.
Using \n at the end of an interactive input format string is a bad idea; the user has to type something that's not a white space character after the input to get the scanf_s() to return.

Related

Difference between "gets(s);" and "scanf("%s", s);" in C

I am writing a program that allows users to enter five names and sorts the names in Alphabet order, two adjacent names seperated by a newline character. Here is my code:
void sortWords(char s[][100], int n){
int i, j;
char *str;
for(i = 0; i < n-1; i++){
for(j = n- 1; j > i; j--){
if(strcmp(s[j], s[j-1]) == -1){
strcpy(str, s[j]);
strcpy(s[j], s[j-1]);
strcpy(s[j-1], str);
}
}
}
}
int main(){
char s[5][100];
int i;
for(i = 0; i < 5; i++){
fflush(stdin);
//gets(s[i]); // when I use this statement, my program doesn't work
scanf("%s", s[i]);
}
sortWords(s, 5);
for(i = 0; i < 5; i++){
printf("%s ", s[i]);
}
return 0;
}
When I changed the "scanf" in function main to "gets", after I have entered 5 names, the program just didn't print anything. Can anyone explain it for me, because normally, when I change one of them to the other function, I just have same results.
allows users to enter five names
Names usually have a space between the parts of the full name. scanf("%s", s) does not read a full name, but only part of a name.
Code has many other problems too.
Difference between "gets(s);" and "scanf("%s", s);" in C
One reads a line the other reads a word.
gets(), since C11 (2011) is no longer part of the C standard library.
Both are bad as they do not limit input and so can suffer buffer overflow.
The obsolete gets() would read and save a line - input unto and including the '\n'. The '\n' is read, but not saved. If the prior input operation left a '\n' in stdin, then gets() reads a short line of "\n" and saves as "".
scanf("%s", s) reads and discards any number of leading white-space characters (perhaps multiple '\n') and then reads and saves non-white-spaces. A following white-space stops the reading, but it is returned to stdin for the next input function.
With common input, scanf("%s", s) typically the leaves the final '\n' in stdin for the next input operation. gets() consumes it.
Both append a null character to s if any reading occurred.
gets() returns a pointer. scanf() returns a conversion count.
Recommendations
Do not use either gets(s) nor scanf("%s", s) in production code. To read a line, research fgets(). To read a word, research using a width like char s[100]; scanf("%99s", s);.
Best to test the return value of I/O functions.
Do not mix fgets()/gets() with scanf() functions until you understand why that is bad.
Other
if(strcmp(s[j], s[j-1]) == -1) is poor. strcmp() returns some negative, zero or some positive to indicate order. Better to use if(strcmp(s[j], s[j-1]) < 0).
strcpy(str, s[j]); is bad as pointer str has not been assigned a value. Better as char str[100]; strcpy(str, s[j]);.
gets() reads a line, scanf("%s") reads a word, and both should not be used.
for details, read #chuxReinstateMonica's answer.

im trying to create a program to reverse a string and if the string has uppercase i must change it to lowercase and vice versa in c

im trying to create a program to reverse a string and if the string has uppercase i must change it to lowercase and vice versa but when i use scanf[^\n] it cant input anything. the input process only succeed in first input
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
int ctr1, ctr2, loop1, loop2;
char char1[1010];
char upp[1010], low[1010];
int len;
scanf("%d", &loop1);
for (ctr1 = 0; ctr1 < loop1; ctr1++) {
scanf("%[^\n]", char1);
len = strlen(char1);
for(ctr2=0;ctr2<len;ctr2++){
upp[ctr2] = toupper(char1[ctr2]);
low[ctr2] = tolower(char1[ctr2]);
if (char1[ctr2] == low[ctr2]) {
char1[ctr2] = upp[ctr2];
}
else if (char1[ctr2] == upp[ctr2]) {
char1[ctr2] = low[ctr2];
}
}
printf("Case #%d: ", ctr1 + 1);
for (ctr2 = len - 1; ctr2 >= 0; ctr2--) {
printf("%c", char1[ctr2]);
}
printf("\n");
}
}
The line
scanf("%[^\n]",char1);
will read everything in the line except for the newline character at the end of the line. When you run this line of code again in the next loop iteration, it will read nothing, because the newline character is still in the input stream.
For this reason, you must also remove the newline character from the input stream.
One simple way of doing this would be to make an additional call to getchar after every scanf call.
Another way of doing this is to instruct scanf to remove all whitespace characters (which includes newline characters) before attempting to match the input, like this:
scanf(" %[^\n]",char1);
However, using the scanf format specifiers %s or %[] without setting a maximum limit is generally not recommended, because a buffer overflow is possible. Therefore, in your case, it would be safer to write
scanf(" %1009[^\n]",char1);
to limit the number of matched characters to 1009, so that the total number of bytes written is limited to 1010 (including the terminating null character). That way, you can be sure that you won't be writing to the array out of bounds.
However, generally I recommend that you use the function fgets instead of scanf, as that function's behavior is more intuitive, as it always reads a whole line at a time (assuming that the provided memory buffer is large enough to store the entire line), including the newline character at the end of the line.

How to set the limit of the for loop to work until end of line/until specific string is reached

So I'm basically trying to make a for loop that scans the input line. The input is always one double float number and then one string. It continues scanning until the string = is reached. Each number value is stored to an array of double and each string to an array of char.
Problem is that the input line can be arbitrarily long and I don't know how to make it
The program should work as a basic calculator which reads one double float, then one operator as a string, and performs operation. If another number follows, then perform the operation with this number. If the equal sign = is reached, the program outputs the result.
int main() {
double res;
double in[10];
char *op[10][5];
int arrCheck[10];
for(int i=0; i<=5; i++) {
scanf("%lf %s ", &in[i], op[i]);
arrCheck[i] = opCheck(op[i]);
}
return 0;
}
This is the main section of my program so far. I managed to get it working and storing the data correctly. Although it always works only on predefined limit (i<=5, for instance). Is it legal to write condition like:
for(i = 0; i<'\n'; i++), or i<=?
I would expect it to continue scanning and storing the data until it reaches the equal sign =.
Try this:
for(int i = 0; (i <= 5) && (strcmp(op[i], "=") != 0); i++) {
...
}
And on your question, it is not legal to compare integers with strings. This is why string comparing functions exist.
You can also break from for loop like this:
int main()
{
double res;
double in[10];
char op[10][5];
int arrCheck[10];
for(int i=0;i<=5;i++){
scanf("%lf %s ", &in[i], op[i]);
if (strcmp(op[i], "=") == 0)
break;
arrCheck[i] = opCheck(op[i]);
}
return 0;
}
Which is even better solution than the one posted previously.
Since you are reading with scanf and the "%s" conversion-specifier, you will consume leading whitespace before each operator stored in op[n]. There is no need to call strcmp, you can simply check the first character by dereferencing the pointer, e.g.
if (scanf ("%lf %s", &in[i], op[i]) != 2 || *op[i] == '=')
break;
A short example omitting opCheck(op[i]) not included in your question, you could do something similar to:
#include <stdio.h>
int main (void) {
double in[10];
char op[10][5];
int i = 0, n;
while (i < 10) {
if (scanf ("%lf %s", &in[i], op[i]) != 2 || *op[i] == '=')
break;
i++;
}
n = ++i;
puts ("\nequation: ");
for (i = 0; i < n; i++)
printf (" %g %s", in[i], op[i]);
puts (" res");
}
(note: the use of while (i < 10) rather than a for (i = 0; i < 10; i++). You do not want to increment i in case of a matching or input failure. You only increment i after validating both conversions succeeded)
Example Use/Output
$ ./bin/eqnread
5.1 + 6 - 2 + 25 * 4 =
equation:
5.1 + 6 - 2 + 25 * 4 = res
So I'm basically trying to make a for loop that scans the input line. The input is always one double float number and then one string.
If you care about lines specifically (which are ended by \n -or by \r on some operating systems), you cannot use scanf alone, because scanf deals with all kind of space characters (including the space, the tabulation, the newline, the formfeed characters) in the same way, so ignores the specificity of end of line characters (\n and/or \r).
So the good way is to read the entire line first with fgets (or getline(3) on Linux) and later to parse that line. Be careful about very long lines, they could happen.
How would you parse that read line is a different question: manual lexing and parsing, or sscanf, or strtok or strtod, etc... come to mind.
And you did not define what a string is for you. What about spaces inside it? What about input lines that are longer than what you expect (e.g. a line of a thousand characters)? The %s for scanf would stop at the first space.
Don't forget to read carefully the documentation of every used function. Learn How to debug small programs.
Be also aware that, practically speaking, in 2019 UTF-8 is used everywhere, and that may add complications to your scheme (and to what strings are in practice).
The program should work as a basic calculator
It seems that you then should care about operator precedence. Then, recursive descent parsing comes to mind.

Counting the Whole String Including The Spaces in C

I'm trying to set up a code that counts the whole string and doesn't stop after the first space that it finds. How do I do that?
I tried this kind of code but it just counts the first word then goes to display the number of letters in that first word.
So far this is what I have tried.
int main(){
char get[100];
int i, space=0, len=0, tot;
scanf("%s", get);
for (i=0; get[i]!='\0'; i++)
{
if (get[i] == ' ')
space++;
else
len++;
}
tot = space + len;
printf("%i", tot);
}
And
int main(){
char get[100];
int len;
scanf("%s", &get);
len = strlen(get);
printf("%i", len);
}
But would still get the same answer as the first one.
I expected that if the
input: The fox is gorgeous.
output: 19
But all I get is
input: The fox is gorgeous.
output: 3
strlen already includes spaces, since it counts the length of the string up to the terminating NUL character (zero, '\0').
Your problem is that that the %s conversion of scanf stops reading when it encounters whitespace, so your string never included it in the first place (you can verify this easily by printing out the string). (You could fix it by using different scanf conversions, but in general it's easier to get things right by reading with fgets – it also forces you to specify the buffer size, fixing the potential buffer overflow in your current code.)
The Answer by Arkku is correct in its diagnose.
However, if you wish to use scanf, you could do this:
scanf("%99[^\n]", get);
The 99 tells scanf not to read more than 99 characters, so your get buffer won't overflow. The [^\n] tells scanf to read any character until it encounters the newline character (when you hit enter).
As Chux pointed out, the code still has 2 issues.
When using scanf, it is always a good idea to check its return value, which is the number of items it could read. Also, indeed the \n remains in the input buffer when using the above syntax. So, you could do this:
if(scanf("%99[^\n]", get) == 0){
get[0] = 0; //Put in a NUL terminator if scanf read nothing
}
getchar(); //Remove the newline character from the input buffer
I will take one example to explain the concept.
main()
{
char s[20], i;
scanf("%[^\n]", &s);
while(s[i] != '\0') {
i++;
}
printf("%d", i);
return 0;
}
i have used c language and u can loop through the ending the part of the string and you will get the length. here i have used "EDIT SET CONVESRION METHOD" to read string, you can also gets to read.

Scanning in strings into a 2D array in C

I need to take an input of 20 words entered by the user put those into a 2D array and print that out
my current code is
char array2[20][20];
int i;
for(i=0;i<20;i++)
{
printf("enter a word\n");
scanf(" %[^\n]",array2[i]);
}
for(i=0;i<colsize2;i++)
{
printf("\n");
for(j=0;j<rowsize2;j++)
{
printf("%c",array2[i][j]);
}
}
(I have no idea what %[^\n] is but it works better than %c or %s)
there are no compiler errors and the program will run but when it prints the array after all the words have been entered all I get is complete garbage
like
aȪ(M▒awn-US▒ e▒(<▒▒t/▒▒▒(5h▒tr:▒(
qh▒tdle__000
HW5.exe▒`wauld▒(▒&Oe,▒*a▒+a▒▒
so much so that it takes a bit of scrolling to get back to the start of my program
I do have more in this program that's not in my question but I'm 99% sure it wouldn't mess with what I have here but if you do want to see the rest just ask
I literally just started programming so I don't know diddly squat about it yet so if you could keep that in mind when you answer also this is for a school assignment so it doesn't need to be perfect it just has to get the job done
thanks to whoever answers this I've been grappling with this for hours
The format string
" %[^\n]"
^ note the leading space
means that scanf will first read and discard any number of leading whitespace characters and then match any sequence of characters which does contain a newline. scanf can potentially overrun the buffer it save the string into if the input string is too large for the buffer invoking undefined behaviour. The %s format specifier means scanf skips the leading whitespace characters and reads the input string till it encounters a whitespace at which point it appends a terminating null byte to the buffer it writes into and then returns.
Therefore, what you need is
char array2[20][20];
int i;
for(i = 0; i < 20; i++)
scanf("%19s", array2[i]);
for(i = 0; i < 20; i++)
printf("%s\n", array2[i]);
Initialize your array to 0:
char array2[20][20] = { 0 } ;
And then print the string not every character:
for(i=0;i<20;i++)
{
printf("%s",array2[i]);
printf("\n");
}

Resources