automatic newline printed in C - c

Here's my code:
void fun1(char data[2][10]);//function prototype
int i, j; char data[2][11];//variables
for (i = 0; i < 2; i++)//populating the 2D array of chars
{
for (j = 0; j < 11; j++)
{
scanf("%c", &data[i][j]);
}
}
fun1(data);
void fun1(char data[2][10])//function to print the array out
{
int i, j, sum;
printf("\n");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 11; j++)
{
printf("%c", data[i][j]);
}
}
}
This is my inputs and outputs:
(inputs)
aaabbbccce
aaabbbccce
(outputs)
aaabbbccce
aaabbbccce
My question is why is there a newline in the output when i haven't specified one?
By the way, is it ok if my function parameters dont match the size of my array? Like my array is char data[2][11] and the parameter i passed in is char data[2][10].

Change all those '11' to '10'
You declareed fun1() as void fun1(char data[][10]), but gave it an argument of type char [][11].
Change scanf("%c", ...) to scanf(" %c", ...)
The space before % will ignore the blank characters, such as newline, in your input.
Your input
aaabbbccce(enter)
aaabbbccce(enter)
includes 22 characters, not 21 ones. The (enter) after the first 'e' should be ignored.
If you use scanf("%c", ...) to read the input, you should give an input like
aaabbbccceaaabbbccce(enter)
to your program.

You should correct the loop limits from 11 to 10.
You should do it in both the functions. But doing it in fun1() should suffice.

I don't think it's ok if your function parameters don't match the array size, at least you wouldn't get what you want.
As we know, when you use array as a parameter, in fact calling function passes its array's first address(aka the variable name of array) to the called function, and called function receives the first address as its parameter's address, so both the parameters share the same memory.
C allows this, but you might see the warning messages.

Related

Why are there random characters outputting in my code?

I have been writing a program to input a phrase and turn it into an acronym. For some reason when I output my acronym at the moment it comes out with a bunch of random characters. How do I fix it?
#include <stdio.h>
#include <string.h>
#define MAXLEN 50
int main() {
int num;
printf("Enter number of acronyms to add to the database:");
scanf("%d", &num);
getchar();
char strings[num][MAXLEN];
char acronym[num][MAXLEN];
for(int i = 0; i < num; i++){
printf("Enter the string to convert into an acronym:");
fgets(strings[i],MAXLEN,stdin);
printf("%s\n", strings[i]);
for(int j = 0; j < 11; j++){
if((strings[i][j]) >= 'A' && (strings[i][j]) <= 'Z'){
char buffer[][20] = {strings[i][j]};
strcat(acronym[i], buffer[i]);
}
}
puts(acronym[i]);
}
return 0;
}
I have tried changing the MAXLEN value to see if it was a memory issue or like a buffer overload. I've also just tried changing around how the strings switch and work together but nothing has worked.
char buffer[][20] = {strings[i][j]};
Here you let the compiler count how many elements the array has from the initialization.
It has 1 element, A string with single a single character strings[i][j] and rest of the 20 byte array filled with 0.
strcat(acronym[i], buffer[i]);
Here you access buffer[i], but there is only one string there (as explained above), so this is invalid if i is anything but 0.
I'm not sure what you are trying to do, but this would be valid implementation of what this code tries to do:
// extract single character as a string
char buffer[2] = {strings[i][j], 0}; // only one of 2 and 0 is mandatory
// append it to acronym
strncat(acronym[i], 20, buffer);
Probably lots of other stuff there is wrong, but here is one definite issue and a possible solution.

Why won't this array get printed?

I'm trying to write a program to take 10 words as input from the user, then store it an array, and then print out the length of each word.
Here's my code:
#include <stdio.h>
#include <string.h>
char *words[10];
char length[10];
int i, j;
int main()
{
printf("Input ten words: \n");
for(i = 0; i < 10; i++)
{
printf("Enter element %d \n", i + 1);
scanf("%s", &words[i]);
}
for(i = 0; i < 10; i++)
printf("%c", words[i]);
for(i = j = 0; j < 10; j++)
{
length[j] = strlen(words[i]);
i++;
}
for(j = 0; j < 10; j++)
printf("%c", length[j]);
return 0;
}
It should be noted that I have no idea why the array "words" is defined as a pointer, I only do it because if I don't I get some warning about making a pointer from integer without a cast.
When I run the program what happens is, I get prompted to input the 10 elements, that much works, but then when it's supposed to print the "words" array, the program just crashes.
Also the reason I coded it like this is because later on I also need to print the longest and shortest word - so I figured it would help if I had the lengths of all the strings in their own array.
Does anyone know what's wrong here?
Thanks
With the line char *words[10], you are declaring an array of 10 pointers. However, these pointers are uninitialized, which means they are wild pointers. Dereferencing a wild pointer causes undefined behavior (i.e. the program may crash). If you want to use these pointers in a meaningful way, you must make each pointer point to a valid memory location, for example to an address returned by the function malloc or to the address of a char array.
However, probably the easiest solution to your problem is to not use pointers at all, but to instead declare a two-dimensional char array, like this:
char words[10][100];
That way, you are allocating space for 10 words of up to 100 characters each (including the null terminating character).
Beware that a buffer overflow will occur if the user enters a word longer than 99 (1 byte is required for the terminating null character). Therefore, the scanf line should be changed to the following:
scanf("%99s", words[i]);
That way, scanf will never attempt to write more than 100 bytes (including the terminating null character).
I have also removed the & in the scanf line above, because the & is not necessary, since words[i] will automatically decay to &words[i][0].
Also, as a general rule, you should verify that the return value of scanf is 1 before attempting to use the value that scanf wrote. For example, if the user triggers end of file on the input stream (for example by pressing CTRL-D on Linux or CTRL-Z on Windows), then scanf will return -1 without writing anything into words[i]. In that case, by subsequently reading from words[i], your program will cause undefined behavior.
Additionally, the line
printf("%c", words[i]);
must be changed to:
printf("%s", words[i]);
The loop
for(i = j = 0; j < 10; j++)
{
length[j] = strlen(words[i]);
i++;
}
can be simplified to:
for(i = 0; i < 10; i++)
{
length[i] = strlen(words[i]);
}
The line
printf("%c", length[j]);
should probably be changed to
printf("%hhu", length[j]);
because length[j] does not represent the ASCII code of a character, but just a number.

I'm just trying to scan strings into an array. What am I doing wrong?

#include <stdio.h>
#include <string.h>
int main(void) {
const int NUM_VALS = 20;
int i;
int actualInput;
char userString[actualInput][NUM_VALS];
int matchCount = 0;
scanf("%d", &actualInput);
for (i = 0; i < actualInput; ++i) {
scanf("%s", userString[i]);
printf("%s", userString[i]);
}
return 0;
}
Output:
b'hellohi\x80\x07#\xd2\x05#\x9a\x16[\xea\xccp\xa6\x15\xf6\x18+\xbf\x87\x8a#\x14)\x05#\xfe\x7f'b'\x92\x1fk\xb3\xfe\x7f\xfe\x7f\x118\x08\xe8\x03\x0eY\x03k\xb3\xfe\x7f\xfe\x7f\xb2Y{\xe8C}8\r\x8b-u{\x8cx86_64'F-8sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin/usr/sbin:/usr/bin:/sbin:/binsbin:/binTF-88tf8RELOAD=/usr/lib/x86_64-linux-gnu/coreutils/libstdbuf.so64-linux-gnu/coreutils/libstdbuf.sols/libstdbuf.soout
I've tried some variations replacing userString[i] with userString in the scanf function. The result is outputting 50,000 inputs of my last string. I don't understand what's happening.
The problem is this sequence of code:
int actualInput;
char userString[actualInput][NUM_VALS];
int matchCount = 0;
scanf("%d", &actualInput);
The first line declares a variable called actualInput but doesn't assign a value to that variable.
The second line declares a variable length array (VLA) using the value in actualInput. Using the value of an uninitialized variable results in undefined behavior, which basically means that after that point in the code, anything can happen. What's likely happening (based on your description of the problem) is that actualInput is either zero, or a small number, so you get an array that's too small to hold your input.
The last line (with the scanf) finally assigns a value to actualInput. You may be thinking that the array will resize itself when actualInput is changed. That definitely does not happen. In C, after a VLA is created, its size cannot be changed.
The solution is simple, rearrange the code so that things are done in the proper order:
int actualInput;
scanf("%d", &actualInput);
char userString[actualInput][NUM_VALS];
int matchCount = 0;
As a side note, you should really do some error checking to make sure that the user inputs a reasonable number, before using that number to create an array. For example
int actualInput;
if (scanf("%d", &actualInput) != 1 || actualInput < 1 || actualInput > 1000)
{
printf("That is not a valid array size\n");
return 1;
}
char userString[actualInput][NUM_VALS];
you cant declare it as a 2D array then treat it as a normal array .
each case should include only one letter but it can't be done automatically , I suggest you add this :
for (i = 0; i < actualInput; ++i)
{
gets(stri);
for (k=0;k<strlen(stri);k++)
userString[i][j]=stri[j];
}

Why can't I list strings stored in arrays?

I started learning C recently. I'm having some difficulty with strings, especially in the matter of storing list of names, phrases, words and displaying them later. Here's my code:
#include <stdio.h>
int main()
{
char names[3][10];
printf("Type 3 names: \n");
for (int i = 0; i<3; i++)
{
scanf("%10s", names);
}
printf("\n\nName list:\n\n");
for (int j = 0; j<3; j++)
{
for (int k = 0; k<10; k++)
{
printf("%s", names[k][j]);
}
}
return 0;
}
My intention is to store full names and with spaces and display them listed later.
When I run the code, the program does not ask for 3 names and does not display correctly the ones that have been typed.
Any tips on how I can fix it?
Please turn up the warning level of your compiler. It should have warned you about at least two things:
(20): warning C4477: 'printf' : format string '%s' requires an argument of type 'char *', but variadic argument 1 has type 'int'
(20): warning C4313: 'printf': '%s' in format string conflicts with argument 1 of type 'int'
In your first for-loop you do count to 3 but you miss specifying that you want to read from stdin to names[i]. Change
scanf("%10s", names);
to
scanf("%10s", names[i]);
In your second loop the nested for-loop is not neccessary since printf() will take care of printing each char in names[j] until it encounters a '\0' which terminates the string. So change
for (int j = 0; j<3; j++)
{
for (int k = 0; k<10; k++)
{
printf("%s", names[k][j]); // doesn't match. names[i][j] is a char *)
}
}
*) which propagates to an int due to parameter passing to a function with a variable length parameter list while the format string "%s" causes printf() to expect a pointer to char.
to
for (int j = 0; j < 3; j++)
{
printf("%s\n", names[j]);
}
Please also mind that since you want to read names up to 10 characters in length your array needs to be
char names[3][11]; // not [3][10]
to accomodate for the terminating '\0' character.

C: Format %s expects argument of type char* in funny strings program

I am making a program to check for funny strings. To understand the exercise read this.
My code is here:
#define MAX_STR_LENGTH 10
char* reverse(char *str) {
char *reversedStr = malloc(strlen(str));
for (int i = 0; i < MAX_STR_LENGTH; i++) {
for (int j = MAX_STR_LENGTH - 1; j > 0; j--) {
reversedStr[i] = str[j];
}
}
return reversedStr;
}
int isFunny(char *str, char *reversedStr) {
for (int i = 1; i < MAX_STR_LENGTH; i++) {
if (str[i] - str[i - 1] != reversedStr[i] - reversedStr[i - 1]) {
return 0;
}
}
return 1;
}
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int numberOfStrings;
scanf("%i", &numberOfStrings);
char **strings;
for (int i = 0; i < numberOfStrings; i++) {
scanf("%s", &strings[i]);
}
char **reversedStrings;
for (int i = 0; i < numberOfStrings; i++) {
reversedStrings[i] = reverse(strings[i]);
}
for (int i = 0; i < numberOfStrings; i++) {
if (isFunny(strings[i], reversedStrings[i])) {
printf("Funny\n");
}
printf("Not funny\n");
}
return 0;
}
The error I am getting is the following:
solution.c: In function 'main':
solution.c:35:9: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char **' [-Wformat=]
scanf("%s", &strings[i]);
I don't understand why though.
My aim was to make an array of strings, called strings, and store there all the strings that I read. Why is strings[i] a char** ?
I would appreciate any help or tips.
Thanks!
Apparently you have a char * and you are passing it's address, which is wrong, scanf() wants a char pointer for each "%s" specifier, and the fix for your code is to use
char string[10];
scanf("%s", string);
the array automatically becomes a char pointer when passed to scanf() like above, but that's not enough.
Your array of char now as I suggest it is of fixed size, and even if it wasn't, using scanf() like that is dangerous, suppose that each array in the array of char arrays has 10 elements, then each string you want to read must have only 9 characters, you can instruct scanf() to stop reading when it already read 9 characters like this
scanf("%9s", strings[i]);
If you don't do this, then reading extra characters will be possible, but illegal, causing what's called undefined behavior.
If you want an array of strings, say of 5 strings with 9 characters each, then you can try
char strings[5][10];
int i;
for (i = 0 ; i < 5 ; ++i)
scanf("%9s", strings[i]);
Note: You need the & address of operator for example, when you pass an int value, because scanf() modifes the data pointed to by the passed pointer, so you need to make a pointer to the int variable where you want to scan the value, for that you use the & address of operator, since you pass a pointer containing the address of the variable.
Suggestion: Always check the return value of malloc(), it returns NULL on failure, and dereferencing a NULL poitner, is undefined behavior, you must be careful not to cause undefined behavior because it's too hard to debug.

Resources