I´m getting a "Access violation writing location" error when I run that code. I know that probably is because I´m trying change a const value, but I dont know how correct the code.
OBS: I want create n arrays to storage strings with 25 characters.
#include <stdio.h>
#include <stdlib.h>
int main() {
//variables
int i = 0, n = 0;
//code
scanf("%d\n", &n); //define the number of arrays
char* exp;
exp = (char*)malloc(n * 25); //allocate memory for the string size
for (i = 0; i < n; i++)
{
//takes strings from keyboard
fgets(exp[i], n*25, stdin); //the below error takes place here.
}
//prints the first string taked from stdin
printf("%s", exp[0]);
}
ERROR:
Exception thrown at 0x00007FFBC6EC916F (ucrtbased.dll) in BEE-URI 1022.exe: 0xC0000005: Access violation writing location 0xFFFFFFFFFFFFFFCD.
The first argument expression of this call shall have the type char *, So instead of
fgets(exp[i], n*25, stdin);
you need at least to write
fgets(exp, n*25, stdin);
And the used conversion specifier
printf("%s", exp[0]);
is also incorrect. Either use
printf("%c", exp[0]);
or
printf("%s", exp);
Pay attention to that it is unclear what you are trying to achieve using this for loop
for (i = 0; i < n; i++)
{
fgets(exp, n*25, stdin); //the below error takes place here.
}
Maybe you mean something like the following
char ( *exp )[25];
exp = malloc( n * sizeof( char[25] ) );
for (i = 0; i < n; i++)
{
fgets(exp[i], sizeof( exp[i] ), stdin);
}
// either
// printf( "%s", exp[0] );
// or the loop below
for (i = 0; i < n; i++)
{
printf( "%s", exp[i] );
}
free( exp );
You say you want n arrays of 25 characters each, but what you malloc is one array of n * 25 characters. I think you want something like this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n;
char **exp;
scanf("%d", &n); // get the number of arrays
exp = malloc(n * sizeof *exp); // allocate memory for n string pointers
for (int i = 0; i < n; i++)
exp[i] = malloc(25 * sizeof **exp);
for (int i = 0; i < n; i++)
fgets(exp[i], 25, stdin); // takes strings from keyboard
printf("%s", exp[0]); // print 1st string taken from stdin
}
Note that you should also check the return values from your malloc calls so you know if they succeeded or failed. Same with fgets and scanf.
BTW, remember that a string of 25 characters can only hold 24 characters because you must have room for the terminating null character.
Related
I'm struggling to copy a string within an array at a given index to another array of strings, any suggestions? When trying to print out the value of tempVal at any given index, it doesn't return anything.
#include <stdio.h>
#include <string.h>
int main(void) {
const int NUM_VALS = 20;
int i;
int matchCount = 0;
int actualInput;
scanf("%d", &actualInput);
char userString[actualInput][NUM_VALS];
char tempVal[actualInput][NUM_VALS];
for (i = 0; i < actualInput; ++i) {
scanf("%s", userString[i]);
// printf("%s", userString[i]);
strncpy(userString[i], tempVal[i], strlen(userString[i])); // < -- Not sure how to make work
printf("%s", tempVal[i]); // <-- Doesn't output anything?
}
return 0;
}
use the function which will limit the number of chars read and place the terminatins zero as well
for (int i = 0; i < actualInput; ++i) {
fgets(userString[i], NUM_VALS, stdin);
strcpy(tempVal[i], userString[i]); // < -- Not sure how to make work
printf("%s\n", tempVal[i]); // <-- Doesn't output anything?
}
It is no wonder why you got no appropriate output because with the provided code you high-probably will get a Segmentation fault. Beside this, there are several issues in the code. To explain them all and also answer the heading question would explode the frame. You can see how I corrected the code in my manner below.
char* strcpy ( char* destination, const char* source )
strcpy is a potential risk for causing buffer overflow if the destination char buffer is not large enough to hold the string to be copied by source. This in your case okay, because each buffers, userString[i] and tempVal[i], have the same capacity (amount of char elements), but if the code changes it could be harmful.
Note that you also should limit the amount of input characters when you catch the string from stdin. For this reason, fgets() is safer than scanf(), since it explicitly requires a maximum amount of characters to read.
char* strncpy ( char* destination, const char* source, size_t num );
strncpy fails to append a terminating null character if the first num characters of the source string do not contain a terminating \0.
Rather use snprintf() which is safe to 1. proofs the size of the destination buffer and limits the amount of characters to read and 2. always appends a null character (assuming the scan process was successful and no errors occurred):
#include <stdio.h>
#include <string.h>
int main(void) {
const int NUM_VALS = 20;
int i;
int s_num;
printf("Enter number of strings in array: ");
scanf("%d", &s_num);
getchar();
char userString[s_num][NUM_VALS];
char tempVal[s_num][NUM_VALS];
for (i = 0; i < s_num; ++i) {
printf("Enter string at userString[%d]: ",i);
if(fgets(userString[i],NUM_VALS, stdin) == NULL)
{
// error handling
if(ferror(stdin))
{
// handle I/O error.
}
else if(feof(stdin))
{
// end of file is reached.
}
}
else
userString[i][strcspn(userString[i], "\n")] = 0;
//printf("%s", userString[i]);
}
printf("\n");
for (i = 0; i < s_num; ++i) {
if(snprintf(tempVal[i], sizeof(tempVal[i]), "%s", userString[i]) < 0)
{
// error handling
fprintf(stderr,"Encoding error occurred!");
}
printf("tempValue[%d]: %s\n", i, tempVal[i]);
}
return 0;
}
Output at a test run:
Enter number of strings in array: 3
Enter string at userString[0]: hello
Enter string at userString[1]: world
Enter string at userString[2]: test
tempValue[0]: hello
tempValue[1]: world
tempValue[2]: test
Sorry guys,
I am taking a class and new to C. I was able to figure out how to solve my problem. I appreciate the suggestions for fixing the code, unfortunately they are beyond the scope of what I have learned in my intro course. I had to find word frequencies using a string array and for loops. Here is the complete working code:
#include <stdio.h>
#include <string.h>
int main(void) {
const int NUM_VALS = 20;
int i;
int j;
int matchCount = 0;
int actualInput;
scanf("%d", &actualInput);
char userString[actualInput][NUM_VALS];
char tempVal[actualInput][NUM_VALS];
for (i = 0; i < actualInput; ++i) {
scanf("%s", userString[i]);
strcpy(tempVal[i], userString[i]);
// printf("%s\n", userString[i]);
// printf("%s\n", tempVal[i]);
}
for (i = 0; i < actualInput; ++i) {
matchCount = 0;
for (j = 0; j < actualInput; ++j) {
if (strcmp(userString[i], tempVal[j]) == 0) {
matchCount++;
}
}
printf("%s %d\n", userString[i], matchCount);
}
return 0;
}
How can I input 2 strings which are separated by a new line?
My Problem:
First I need to give how many strings I need to get and then I need to get those strings then display it.
I tried this:
Code:
#include <stdio.h>
#include <string.h>
int main()
{
int n,i = 0;
scanf("%d", &n);
char arr[n][100];
for(int i = 0; i < n; i++)
{
scanf("%[^\n]s", arr[i]);
}
for(int i = 0; i < n; i++)
{
printf("%s\n", arr[i]);
}
return 0;
}
My Input is :
2 I am
Aravind
My Output is:
I am
þ
First Line I got correct one but second line it shows some garbage value. Help me to solve this.
You have two major problems:
The "%[" format ends with the closing "]", there should be no "s" at the end.
The "%[" format doesn't skip leading space, like that newline which will be present after the first line you read.
Both these issues can be easily solve by using fgets to read whole lines instead.
You already have suggestions to not use scanf. However, if you 'must' use scanf then you can consider the following approach:
For dynamic memory allocation you should use malloc
the newline character stays in the stdin and hence needs to be flushed or handled/ignored
Here is the updated code.
int main()
{
int n,i = 0;
scanf("%d", &n);
scanf("%*[\n]");
/*this will read the \n in stdin and not store it anywhere. So the next call to
* scanf will not be interfered with */
char **inputs;
inputs = malloc(n * sizeof(char *));
for (i = 0; i < n; i++)
{
inputs[i] = malloc(100 * sizeof(char));
}
for(i = 0; i < n; i++)
{
scanf("%*[\n]");
scanf("%100[^\n]", inputs[i]);
}
for(i = 0; i < n; i++)
{
printf("%s\n", inputs[i]);
}
return 0;
}
use gets(arr[i]) instead of scanf.
This code don't count words properly. I don't know if it is wrong on the for or what. Need help.
#include <stdio.h>
#include <stdlib.h>
int count_p(char sentence[100]) {
int i, m = 1;
for (i = 0 ; i < 100 ; i++) {
if (sentence[i] == ' ') {
m += 1;
}
}
return(m);
}
void main() {
char s[100];
int p;
printf("Sentence here: ");
scanf("%s", &s[50]);
p = count_p(sentence);
printf("Words: %d", p);
printf("\n");
}
The %s in scanf stops reading when it found a whitespace. Therefore, ' ' won't appear in s unless it was there as indeterminate value in uninitialized variable.
You can use fgets to read a whole line.
Here is a fixed code that also checks for end of the string.
#include <stdio.h>
#include <stdlib.h>
int count_p(char sentence[100]) {
int i, m = 1;
for (i = 0 ; i < 100 && sentence[i] != '\0'; i++) {
if (sentence[i] == ' ') {
m += 1;
}
}
return(m);
}
int main(void) {
char s[100];
int p;
printf("Sentence here: ");
fgets(s, sizeof(s), stdin);
p = count_p(s);
printf("Words: %d", p);
printf("\n");
return 0;
}
scanf("%s", &s[50]);
Not a correct way to take input and writing at index which is out of bound. Do this instead -
scanf("%99[^\n]", s); // this will read 99 characters and until '\n' is encountered
In main you function call is incorrect -
p = count_p(sentence); // sentence is not declares in main
Call like this -
p = count_p(s); // pass s instead of sentence to function
Also in function count_p change ccondition in for loop as -
size_t i;
size_t len=strlen(s);
for (i = 0 ; i < len ; i++)
You see &s[50] means that you pass a pointer to the 51-th element of s, you then try to access s from the beginning but, the first 50 characters in s were not yet initialized, this leads to undefined behavior.
Also, your loop from 0 to 99 will have the same issue since you might input a string of less than 100 characters, in that case you would be accessing uninitialized data too.
You can fix your program by changing this
scanf("%s", &s[50]);
to
scanf("%99s", s);
and then
for (i = 0 ; i < 100 ; i++) {
to
for (i = 0 ; s[i] != '\0' ; i++) {
because scanf() will append a '\0' to make the array a valid c string, that's also the reason for the "%99s".
Another problem is that, if you want white space characters not to make scanf() stop reading, you need a different specifier, because "%s" stops at the first white space character, this is a suggestion
scanf("%99[^\n]", s);
Or you can do as #MikeCAT suggested and go with fgets(). But be careful with the trailing '\n' in case of fgets().
And finally, altough highly unlikely in this situation, scanf() might fail. To indicate success it returns the number of specifiers actually matched, thus it might indicate partial success too. It's fairly common to see the return value of scanf() ignored, and it's very bad when you have a "%d" specifier for example because then the correspoinding parameter might be accessed before initializing it.
The statement scanf("%s", &s[50]); is in correct in your situation.Since you want to enter a sentence separated by spaces,the correct way of doing it is :
scanf(" %99[^\n]s",sentence);
That will prevent buffer overflow and allow space between words.Also your program does not seem to count words correctly if the sentence has consecutive whitespaces.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count_p(char *sentence);
void main()
{
char sentence[100];
printf("Sentence here: ");
scanf(" %99[^\n]s",sentence);
int p = count_p(sentence);
printf("Words: %d", p);
printf("\n");
}
int count_p(char *sentence)
{
int len = strlen(sentence);
int x = 0 , wordCount = 0;
for( int n = 0 ; n < len ; n++ )
{
x++;
if( sentence[n] == ' ' )
x = 0;
if( x == 1 )
wordCount++;
}
return wordCount;
}
I am trying to merge a lot of char arrays into a single one. My task is to change float array into a char array to be sent as a line of data via TCP/IP socket, so I thought to use sprintf to print float array values into a char array and then merge those arrays into a single char array, I wrote a little algorithm, but the data does not form into a single line of data and overwrites the last input, what am I doing wrong? Here is the code:
#include <stdio.h>
#include <iostream>
/*
* Mock data loop - a loop where data is created
* String loop - a loop where a single word is merged into a sentance
* Formating loop - a loop where floats are converted into char arrays
!!! - The place where things go wrong (I think)
*/
using namespace std;
int main(){
float data[5]; // Mock data array
char tmp[10]; // Temprorary array, where a word (flaot value) is stored
char text[256]; // String array, where words are stored into a single sentance
int n=5; // Size of mock data
int i, j, k; // Loop counters
// Mock data loop
for (i = 0; i < n; i++){
data[i] = float(i);
printf("Data: %f \n", data[i]);
}
printf("------------------------- \n");
/////////////////////////////////////////////////////////////////////// !!!
for (i = 0; i < 256; i++){ // String loop
for(j = 0; j < n; j++){ // Mock data loop
for (k = 0; k < 10; k++){ // Formating loop
sprintf(tmp, "%f", data[j]);
printf("Sprintf: %s \n", tmp);
text[i + k] = tmp[k];
}
}
printf("Text %d : %s \n", i, text);
i = i + 9;
}
/////////////////////////////////////////////////////////////////////// !!!
printf("------------------------- \n");
printf("Text: %s \n", text);
std::cin.get();
return 0;
}
Appreciate the help, guys!
P.S. I am trying not to use any C++ functions, because I am working with a microcontroller, this code has been written in MS Visual 2013, so I use #include and std::cin.get(); to halt the console and see the results.
As far as I can tell by your code, you're reserving 10 characters in the line for each float value (you do i++, but also i += 9). What if the string representation for the float requires more positions? Your tmp will overflow and your counting will be off.
Here's an attempt that doesn't use 10 positions, but just as many as necessary. On the receiving side you'd have to split by spaces and sscanf() to get the floats back. The code also checks for buffer overflows. I hope that I've understood your question correctly and that this helps...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
float data[5]; /* Mock data */
char text[256]; /* Line of data */
int i;
/* Build up mock data */
for (i = 0; i < 5; i++)
data[i] = i * 3 + 3.1415729;
/* Stuff int text */
text[0] = 0;
for (i = 0; i < 5; i++) {
char tmp[100]; /* Conversion buffer, should be large enough */
if (snprintf(tmp, sizeof(tmp), "%f ", data[i]) >= sizeof(tmp)) {
fprintf(stderr, "conversion buffer overflow\n");
exit(1);
}
if (strlen(text) + strlen(tmp) >= sizeof(text)) {
fprintf(stderr, "text buffer overflow\n");
exit(1);
}
strcat(text, tmp);
}
printf("Built up text: %s\n", text);
return 0;
}
Im just starting to learn C programming and for exercise i found one task. First i have to scan in two strings. Then i have to compare them character by character and if there are any same characters i have to print out the amount of the same characters.
It has to be done with pointers. So lets i have "boat" and "ship" so the program would return 0. But if it were "boat" and "soap" it would return 2.
This is what i've got so far but when i run it it gives me errors. I put the errors in comments.
Thanks in advance for your help.
#include <stdio.h>
#include <string.h>
int number_of_same_characters(char *, char *);
int main()
{
char * first[100];
char * second[100];
int result = 0;
printf("Enter first string\n");
gets(*first);
printf("Enter second string\n");
gets(*second);
result = number_of_same_characters(*first, *second);
printf("%d\n", result);
return 0;
}
int number_of_same_characters(char *p, char *q){ //i get this error here - error: invalid type argument of unary ‘*’ (have ‘int’)
int counter = 0;
for(int j = 0; *p[j] != '\0' || *q[j] != '\0'; ++j){ //i get this error here - error: invalid type argument of unary ‘*’ (have ‘int’)
if(strcmp(*p[j], *q[j])){
++counter;
}
}
return counter;
}
Mainly you've got a lot of extra *'s littering the program. The variable declarations should be:
char first[100];
char second[100];
The input calls should be†:
gets(first);
gets(second);
The method call should be:
result = number_of_same_characters(first, second);
And finally there shouldn't be any dereferences in the for loop.
for(int j = 0; p[j] != '\0' || q[j] != '\0'; ++j){
if(strcmp(p[j], q[j])){
++counter;
}
}
That'll get you closer, though there are still a couple of problems. As a hint, the || operator is suspect, and you don't need to use strcmp.
† It's worth pointing out that gets() is a dangerous function that can lead to buffer overflows. It's okay to use when you're just starting out, but don't let it become a habit, and don't ever use it in production code!
You defined character arrays incorrectly and incorrectly are using operator *.
Try the following
#include <stdio.h>
#include <string.h>
#define N 100
int number_of_same_characters( const char *, const char * );
int main()
{
char first[N];
char second[N];
int result = 0;
size_t n;
printf( "Enter first string: ");
fgets( first, N, stdin );
n = strlen( first );
if ( first[n - 1] == '\n' ) first[n - 1] = '\0';
printf( "Enter second string: ");
fgets( second, N, stdin );
n = strlen( second );
if ( second[n - 1] == '\n' ) second[n - 1] = '\0';
result = number_of_same_characters( first, second );
printf( "%d\n", result );
return 0;
}
int number_of_same_characters( const char *p, const char *q )
{
int counter = 0;
int i;
for( i = 0; p[i] != '\0' && q[i] != '\0'; ++i )
{
if ( p[i] == q[i] ) ++counter;
}
return counter;
}
If to enter boat and soap then the output will be
2