I am trying to create an array of fixed-length "strings" in C, but have been having a little trouble. The problem I am having is that I am getting a segmentation fault.
Here is the objective of my program: I would like to set the array's strings by index using data read from a text file. Here is the gists of my current code (I apologize that I couldn't add my entire code, but it is quite lengthy, and would likely just cause confusion):
//"n" is set at run time, and 256 is the length I would like the individual strings to be
char (*stringArray[n])[256];
char currentString[256];
//"inputFile" is a pointer to a FILE object (a .txt file)
fread(¤tString, 256, 1, inputFile);
//I would like to set the string at index 0 to the data that was just read in from the inputFile
strcpy(stringArray[i], ¤tString);
Note that if your string can be 256 characters long, you need its container to be 257 bytes long, in order to add the final \0 null character.
typedef char FixedLengthString[257];
FixedLengthString stringArray[N];
FixedLengthString currentString;
The rest of the code should behave the same, although some casting might be necessary to please functions expecting char* or const char* instead of FixedLengthString (which can be considered a different type depending on compiler flags).
Related
I'm using C with no access to libraries or anything like that since this is kernel code for an operating system. So I can not use sizeOf or any built in function like that. name[] is a character array that holds the name of a file, but the file name can be up to 6 characters long, and I want to determine how long the file name actually is.
Right now, my code looks like this:
int length = 0;
while(name[length] != 0x0)
{
length++;
}
I also tried it with the 0x0 replaced with '\0' but it still didn't work.
Ideally, it would iterate through the char array and stop once it reaches the end of the file name, but I'm pretty sure that it keeps going past it.
Probably the array doesn't contain the zero char ('\0') immediately after the last char of your string.
You can solve this directly by adding the '\0' while you are filling-up an array, or by initializing the whole array by '\0' before filling-up.
I have tried using Google, but not really sure how to phrase my search to get relevant results. The programming language is C. I was given a (homework) assignment which requires reading a text file and outputting the unique words in the text file. The restriction is that the only allowable import is <stdio.h>. So, is there a way to use dynamic structures without using <stdlib.h>? Would it be necessary to define those dynamic structures on my own? If this has already been addressed on Stack Overflow, then please point me to the question.
Clarification was provided today that the allowable imports now include <stdlib.h> as well as (though not necessary or desirable) the use of <string.h>, which in turn makes this problem easier (and I am tempted to say trivial).
It is telling that you couldn't find anything with Google. Assignments with completely arbitrary restrictions are idiotic. The assignment tells something profound about the quality of the course and the instructor. There is more to be learnt from an assignment that requires the use of realloc and other standard library functions.
You don't need a data structure, only a large enough 2-dimensional char array - you must know at compile time how long words you're going to have and how many of them are there going to be at most; or you need to read the file once and then you're going to allocate a two-dimensional variable-length array on the stack (and possibly blow the stack), reset the file pointer and read the file again into that array...
Then you read the words into it using fgets, loop over the words using 2 nested for loops and comparing the first and second strings together (of course you'd skip if both outer and inner loop are at the same index) - if you don't find a match in the inner loop, you'll print the word.
Doing the assignment this way doesn't teach anything useful about programming, but the only standard library routine you need replicate yourself is strcmp and at least you'll save your energy for something useful instead.
It is not possible to code dynamic data structures in c using only stdio.h. That may be one of the reasons your teacher restricted you to using just stdio.h--they didn't want you going down the rabbit hole of trying to make a linked list or something in which to store unique words.
However, if you think about it, you don't need a dynamic data structure. Here's something to try: (1) make a copy of your source file. (2) declare a results text file to store your results. (3) Copy the first word in your source file to the results file. Then run through your source file and delete every copy of that word. Now there can't be any duplicates of that word. Then move on to the next word and copy and delete.
When you're done, your source file should be empty (thus the reason for the backup) and your results file should have one copy of every unique word from the original source file.
The benefit of this approach is that it doesn't require you to know (or guess) the size of the initial source file.
Agreed on the points above on "exercises with arbitrary constraints" mostly being used to illustrate a lecturers favorite pet peeve.
However, if you are allowed to be naive you could do what others have said and assume a maximum size for your array of unique strings and use a simple buffer. I wrote a little stub illustrating what I was thinking. However, it is shared with the disclaimer that I am not a "real programmer", with all the bad habits and knowledge-gaps that follows...
I have obviously also ignored the topics of reading the file and filtering unique words.
#include <stdio.h> // scanf, printf, etc.
#include <string.h> // strcpy, strlen (only for convenience here)
#define NUM_STRINGS 1024 // maximum number of strings
#define MAX_STRING_SIZE 32 // maximum length of a string (in fixed buffer)
char fixed_buff[NUM_STRINGS][MAX_STRING_SIZE];
char * buff[NUM_STRINGS]; // <-- Will only work for string literals OR
// if the strings that populates the buffer
// are stored in a separate location and the
// buffer refers to the permanent location.
/**
* Fixed length of buffer (NUM_STRINGS) and max item length (MAX_STRING_SIZE)
*/
void example_1(char strings[][MAX_STRING_SIZE] )
{
// Note: terminates when first item in the current string is '\0'
// this may be a bad idea(?)
for(size_t i = 0; *strings[i] != '\0'; i++)
printf("strings[%ld] : %s (length %ld)\n", i, strings[i], strlen(strings[i]));
}
/**
* Fixed length of buffer (NUM_STRINGS), but arbitrary item length
*/
void example_2(char * strings[])
{
// Note: Terminating on reaching a NULL pointer as the number of strings is
// "unknown".
for(size_t i = 0; strings[i] != NULL; i++)
printf("strings[%ld] : %s (length %ld)\n", i, strings[i], strlen(strings[i]));
}
int main(int argc, char* argv[])
{
// Populate buffers
strncpy(fixed_buff[0], "foo", MAX_STRING_SIZE - 1);
strncpy(fixed_buff[1], "bar", MAX_STRING_SIZE - 1);
buff[0] = "mon";
buff[1] = "ami";
// Run examples
example_1(fixed_buff);
example_2(buff);
return 0;
}
I want to perform some lengthy operations on a large file, which will involve lots and lots of seeking. (The current version of the program takes 5 hours and uses fseek at least 15,057,456 times.) As a result, I am hoping to load the file into the ram, and use char* instead of FILE*. Can I load null characters from the file into the char* array if I:
Malloc the char array, and store its length separately, and
Only use character operations on the array (i.e. newchar = *(pointertothearray+offset) ), avoiding operations like strcpy or strstr?
You can load the whole file in a dynamic char array (malloc'ed on the heap) even if there are null characters in it : a null character is a valid char.
But you cannot call it a string. A C string is from specification of language a null terminated char array.
So as long as you only use offsets, mem... functions and no str... functions, there is no problems having null characters in a char array.
You can load the entire file's contents into memory. Essentially this buffer will be a byte stream and not a string.
The program should be able to make an array of numbers from a text file which reads like this
The data is given as this
123 2132 1100909 3213 89890
my code for it is
char a;
char d[100];
char array[100];
a=fgetc(fp) // where fp is a file pointer
if (a=='')
{
d[count1]='/0';
strcpy(&array[count],d);
count=count+1;
memset(d,'\0',100)
count1=0;
}
else
{
d[count1]=a;
count1=count1+1;
}
a=fgetc(fp);
i am getting segmentation fault now . want to store each number in the array so that i can do sorting on it
Your (first) problem is here:
d[count1]='/0';
strcpy(&array[count],d);
You have written '/0', which isn't what you think it is. Assuming you meant '\0' (a null char literal), then you appear to be trying to manually terminate the string d before calling strcpy(). The problem is that what actually gets written to d is not a null byte, and so d is not null-terminated, and then strcpy() goes off and starts reading random memory after it, and copying that memory into array, until either the reading or the writing ends up outside of memory you're allowed to access, and you get a segmentation fault.
You also have some confusion about that array is. It's declared as an array of 100 chars, but you're treating it like it's an array of strings. Perhaps you meant to declare it as char *array[100] ?
Hmm...as a first approximation, to read a single number, consider using fscanf("%d", &number);. To store the numbers you read, you'll probably want to create an array of numbers (e.g., int numbers[100];). To read more than one number, use a loop to read the numbers into the array.
Sidenote: fscanf isn't particularly forgiving of errors in the input (among other things) so for production code, you probably want to read a string, and parse numbers out of that, but for now, it looks like you probably just need to get something that works for correct input, not worry about handling incorrect input gracefully.
Is this actually how the code is written?
In d[count1]='/0'; I think you mean d[count1]='\0'; (already mentioned by Daniel Pryden).
There is also a semicolon missing at the end of memset(d,'\0',100)
I'm using a char[] of size 4 but when I use memcpy() function it stores 8 characters in it and also the character array length becomes 8. What is happing?
I don't want to use malloc ok.
char strRoh[4]={'\0'};
and then
memcpy(strRoh,Dump+22,4);
Now tell me whats wrong with this
char strIP[]="hhhhhhhh";
char strRoh[4]={'\0'};
char strTheta[4]={'\0'};
char strTimeStamp[6]={'\0'};
char strNMDump[48]={'\0'};
is there any problem with decelerations cause when i change there order they strings also change there size now strroh is getting 10 chars
what a hell is going on with this
C strings are 0-terminated. This means that if you want to have a string of length n in C, you need n+1 chars for it:
char hello[5] = "hello";
is not a string, because hello has space for 5 chars, and it doesn't end with 0.
char hello[6] = "hello";
is a string, and has 6 characters: h, e, l, l, o, 0.
To be able to use string related functions in C, you need the terminating 0.
So, change your code to have:
char strRoh[5]={'\0'};
char strTheta[5]={'\0'};
char strTimeStamp[7]={'\0'};
char strNMDump[49]={'\0'};
Note that in C, when you do:
char hello[] = "hello";
the compiler does the counting for you, and makes hello an array of size 6 (one terminating 0):
printf("%zu\n", sizeof hello);
will print 6.
The underlying type of the objects pointed by both the source and destination pointers are irrelevant for memcpy; The result is a binary copy of the data.
The function does not check for any terminating null character in source - it always copies exactly num bytes. My guess is you are not adding a terminating null and trying to access it as a string.
C does not have any kind of boundary check on its data types.
So what you are probably "seeing" when debugging the code is that it shows you 8 bytes in the array. As someone else says, you might be trying to view it as a string and do not have a terminating zero byte. This is quite normal in C, and it is one of the aspects of the language that makes it very hard to understand.
I can recommend you read a good introduction to memory and pointer handling under C, or switch to a managed language like C#, VB.NET, Java, Perl, Python etc.
I suppose that if char has 2 bytes if you memcpy to a byte array you might be getting 8 bytes, that is 2 bytes for each char.
I am however rusty at this C/C++ things. So hopefully somebody with more experience will give you a better answer.
The problem is you have a char array of 4 bytes and you writing full 4 bytes during memcpy without leaving any space for the terminating null character. Declare your array as 5 bytes and initialize it all to null (which you are already doing) and everything should be fine.