This question already has an answer here:
Dynamic Memory Allocation
(1 answer)
Closed 8 years ago.
I'm having trouble dynamically allocating memory for an array.
The program is simply supposed to exchange the swap the first row with the second, and the third with the forth. I am getting strange results like:
Enter string: hello
Enter string: how are you
Enter string: i'm good thanks
Enter string: bye
Enter string: bai
Enter string: xx
=========================
how are you
!i'm good thanks
hello
!how are you
bye
!bai
i'm good thanks
!bye
bai
!xx
int count = 0;
char *lines[MAX_LINES];
char *tmp[50];
printf("Enter string: ");
fgets(tmp, 50, stdin);
lines[count] = (char *) malloc((strlen(tmp)+1) * sizeof(char));
strcpy(lines[count], tmp);
while(strcmp("xx\n", lines[count])){
count++;
printf("Enter string: ");
fgets(tmp, 50, stdin);
lines[count] = (char *) malloc((strlen(tmp)+1)* sizeof(char));
strcpy(lines[count], tmp);
}
void exchange(char * records[])
{
char * temp;
temp = records[0];
records[0] = records[1];
records[1] = temp;
temp = records[2];
records[2] = records[3];
records[3] = temp;
}
void printArray(char * inputs[], int row, int col)
{
int i, j;
for(i = 0; i < row; i++){
for(j = 0; j < col; j++){
printf("%c", inputs[i][j]);
}
}
}
This is not good:
char *tmp[50];
You intended to do this:
char tmp[50];
Strangely enough, it'll kinda work, but your compiler should have been throwing up warnings everywhere.
I think your main problem is your printArray function, which doesn't check for the NULL terminator in a string. So it's gonna run right off the end of most of them.
Instead of printing character-by-character, do this:
void printArray(char * inputs[], int length)
{
int i;
for(i = 0; i < length; i++){
printf("%s", inputs[i]);
}
}
Here's a tip on using malloc. Don't cast the result, and if you're reserving space for char values, don't use sizeof(char) -- it's always 1.
lines[count] = malloc( strlen(tmp) + 1 );
Related
I'm trying to create a program which the user inputs the number of items (rows) and give each one of them a name (scanf) with the max of 30 characters.
I want to create this code with pointers of pointers, once that I'm learning this on C.
I'm having some difficulties with the code.
Draft of the 2D array.
Code snippet:
PS: #define MAX 31
char **items = NULL, *columns = NULL, name[MAX];
int rows, aux_rows;
printf("\nNumber of items:\n");
scanf("%d", &rows);
items = (char **) malloc(rows * sizeof(char*));
for (aux_rows = 0; aux_rows < rows; aux_rows++){
columns[aux_rows] = (char *) malloc(MAX * sizeof(char));
}
for (aux_rows = 0; aux_rows < rows; aux_rows++){
printf("\nName of item %d:\n", (aux_rows + 1));
scanf("%s", name);
*items[aux_rows] = name;
}
items was allocated and not columns. And use strcpy to copy the characters.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 31
int main()
{
char **items = NULL, *columns = NULL, name[MAX];
int rows, aux_rows;
printf("\nNumber of items:\n");
scanf("%d", &rows);
items = (char **)malloc(rows * sizeof(char *));
for (aux_rows = 0; aux_rows < rows; aux_rows++)
{
items[aux_rows] = malloc(MAX * sizeof(char));
}
for (aux_rows = 0; aux_rows < rows; aux_rows++)
{
printf("\nName of item %d:\n", (aux_rows + 1));
scanf("%s", name);
strcpy(items[aux_rows], name);
}
return 0;
}
$ gcc array2d.c
$ ./a.out
Number of items:
2
Name of item 1:
Hello
Name of item 2:
World!
$
*items[aux_rows] = name;
is wrong on two counts.
Both * and [] dereference their unary operand. If items is a char **, items[n] is a char *, and *items[n] is a char.
This attempts to assign an array to the first element of each buffer.
Secondly, arrays cannot be copied by assignment. Use strcpy to copy strings from one buffer to another.
That said, you could simply read your strings directly into the pre-allocated buffers, and do away with the temporary buffer.
In this line,
columns[aux_rows] = (char *) malloc(MAX * sizeof(char));
columns should be items.
Some things of note:
sizeof (char) is guaranteed to be 1. Its use is superfluous.
The return of malloc should not be cast in C.
malloc can fail. scanf can fail. You should get in the habit of not ignoring return values.
scanf("%s", ...) is as dangerous as gets. At a minimum, use field-width specifiers to limit input (should be the size of your buffer minus one).
char foo[128];
if (1 != scanf("%127s", foo))
/* handle error */;
Note that using the %s limits input to not contain any whitespace. scanf in general is a terrible tool, consider a line based approach using fgets.
With that said, the minimum changes to make this reasonably safe:
#include <stdio.h>
#include <stdlib.h>
#define MAX 31
void die(const char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}
int main(void)
{
size_t rows;
printf("Number of items: ");
if (1 != scanf("%zu", &rows))
die("Failed to read input.");
char **items = malloc(sizeof *items * rows);
if (!items)
die("Failed to allocate memory.");
for (size_t i = 0; i < rows; i++) {
if (!(items[i] = malloc(MAX)))
die("Failed to allocate row.");
printf("Name of item %zu: ", i + 1);
if (1 != scanf("%30s", items[i]))
die("Failed to read item input.");
}
for (size_t i = 0; i < rows; i++) {
puts(items[i]);
free(items[i]);
}
}
The code is supposed to take in as many string as the user wants to put in until they enter EOF. and it is doing that but after i try to ouput the code it comes out with these little half boxes instead of the string.
void sortString(char *s[], int count);
int main(){
int i;
char buff[BUFSIZ];
int count;
char** s = (char**)malloc(sizeof(char*));
//allows user to keep typing until EOF is reached.
printf("Here is the list of unsorted names: \n\n");
for (count = 0; fgets(buff, sizeof(buff), stdin); count++)
{
s[count] = malloc((sizeof(buff))*sizeof(char));//allocats memory at s[count].
strcpy(buff, s[count]);//adds the string in buff to s[count].
s = (char**) realloc(s, ((sizeof(s) + sizeof(buff)) * sizeof(char*)) + 1);//then reallocats memeory for s to take another string.
}
printf("\nCount is %d\n\n", count);
// Now sort string using sortString function
// Step 4: implement sortString function for the above-mentioned function declaration
for (i = 0; i < count; i++){
printf("%s \n",s[i]);
}
sortString(s, count);
printf("Here is the list of sorted names: \n\n");
for (i = 0; i < count; i++){
printf("%s",s[i]);
}
strcpy(buff, s[count]);//adds the string in buff to s[count].
No it doesn't. strcpy(dest, src), so it is copying s[count] (which is a buffer full of "random junk") to buff.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
This is the text of my example:
Loading number N then N words from standard input. The word is not longer than 100 characters. Dynamically allocate array of loaded words as a series of pointers to character strings (dynamic array needs to have a type char **). Provide a set of words printed in a single line with spaces between the words.
Can someone tell me how to set the character limits?
Should I do this:
scanf("%100s", str[i])
or something else?
BTW, how can I allocate the memory for a type like this (char **,int **,etc)?
This is my code that I've done, so what have I done wrong?
int main()
{
int i,n;
printf("How much words? "), scanf("%d", &n);
char *str= (char *)malloc(n*sizeof(char *));
for(i = 0; i < n; i++)
{
str[i] = malloc(100 * sizeof(char *));
printf("%d. word: ", i + 1),scanf("%s", str[i]);
}
for (i = 0; i < n; i++)
{
printf("%s ", str[i]);
}
getch();
Wrong type for array of pointers
// char *str
char **str
Code clean-up with comments.
// add void
int main(void) {
int i,n;
// Easier to understand if on 2 lines-of code
printf("How much words? ");
// test scanf() results
if (scanf("%d", &n) != 1) return -1;
// Consider different style to allocate memory, as well as type change
// char *str= (char *)malloc(n*sizeof(char *));
char **str= malloc(sizeof *str * n);
// check allocation
assert(str == NULL);
for(i = 0; i < n; i++) {
str[i] = malloc(sizeof *str[i] * 100);
// check allocation
assert(str[i] == NULL);
printf("%d. word: ", i + 1);
fflush(stdout);
// limit input width to 99
// test scanf() results
if (scanf("%99s", str[i]) != 1) return -1;
}
for (i = 0; i < n; i++) {
// Add () to clearly show beginning/end of string
printf("(%s) ", str[i]);
}
getch();
}
I want to reverse a char array using pointers, but all I get when I printf the pointer is null. I don't know what I'm doing wrong or how to fix it. So how can I reverse the string in a similar way?
#include <stdio.h>
void reverse(char *cstr);
int main()
{
char a[100];
char *p = a;
printf("geef een string "); // ask user to write a word
scanf("%s", &a);
reverse(p);
printf("%s", *p);
}
void reverse(char *p)
{
int i = 0;
char temp;
int lengte;
for(i = 0; *(p+i) != '\0'; i++)
{
lengte++; // length of char array without the '\0'
}
for(i = 0; i < lengte; i++)
{
temp = p[i]; // something goes wrong here but I don't know what
p[i] = p[lengte-i];
p[lengte-i] = tem;
}
}
Something goes wrong at the
p[i] = p[lengte-i];
p[lengte-i] = tem;
part. What do I need to change it to?
Two adjustments:
replace
printf("%s", *p);
with
printf("%s", p);
because printf is expecting a pointer, not a dereferenced pointer,
and
for(i = 0; i < lengte; i++)
with
for(i = 0; i < lengte--; i++)
because your counting of the length in the loop before that one ends up with one char too many. Hence the \0 is placed at the beginning of the string.
$ gcc test.c && ./a.out
geef een string 1234
4231$
I am learning about C pointers by creating various simple functions. I have just created a function to reverse a char array. It works, but after the output it also displays a bunch of garbage chars (see screenshot below).
Here's my code:
void reverseString();
int main()
{
reverseString();
system("PAUSE");
return 0;
}
void reverseString()
{
char string1[20], string2[20];
char *ptr1, *ptr2;
ptr1 = &string1[0];
ptr2 = &string2[0];
printf("Enter string: \n");
scanf("%s", string1);
int len1 = strlen(string1);
int i;
for (i = 0; i < len1; i++)
{
ptr2[i] = ptr1[len1 - i - 1];
}
printf("%s\n", string2);
}
How can I get rid of the garbage chars? Is there something wrong with my code or did I just nto account for something or what?
You forgot to nul-terminate the new string:
int i;
for (i = 0; i < len1; i++)
{
ptr2[i] = ptr1[len1 - i - 1];
}
// Add this
ptr2[i] = '\0';
When you print a char*, it will keep reading until it finds that nul character. But since you left it out, it kept going and going...