#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char* argv[]) {
char *filename = argv[1];
char *store = malloc(2);
FILE *fh = fopen(filename, "wb");
for(int i = 0; i < 100; i++) {
sprintf(store, "%u", i);
if (fh != NULL) {
fwrite (store, sizeof (store), 1, fh);
}
}
fclose (fh);
return 0;
}
I want my output to look like this -> https://imgur.com/a/nt2ly. The output it produces currently is all garabge.
The real reason for the garbage is the size of your data on the fwrite statement
fwrite (store, sizeof (store), 1, fh);
sizeof(store) is not the size of the string. It's the size of the pointer.
Aside, allocating 2 bytes for store is wrong. You're forgetting that a 2-digit number as a string needs space for a nul-terminator, so you're writing one char too many.
More minor issue: why testing the handle against NULL in the loop? you could exit in that case.
Also test the argument length (argc).
int main(int argc, char* argv[]) {
if (argc<2) exit(1); // protect against missing arg
char *filename = argv[1];
char store[50]; // use auto memory, faster & simpler, don't be shy on the size, don't shave it too close
FILE *fh = fopen(filename, "wb");
if (fh != NULL) { // test file handle here, not in the loop
for(int i = 0; i < 100; i++) {
// sprintf returns the number of printed chars, use this
// also use the proper format specifier for int
int nb_printed = sprintf(store, "%d", i);
// you may want to check the return value of fwrite...
fwrite (store, nb_printed, 1, fh);
}
fclose (fh);
return 0;
}
Note that this code will create a binary file with all numbers collated:
01234567891011...
so hardly useable. I would perform a sprintf(store, "%d ", i); instead to add spacing between the numbers.
Also note that if you wanted to write characters in a file, you'd be better off with:
fprintf(fh,"%d ",i);
(but I suppose the main point is to learn to use fwrite)
Related
I have a C project where the user can type in an 8 bit binary number or open up a text file with an 8 bit binary number. What I'm having trouble with is getting the 8 bit binary number from a file and making that an argument char* argv[] for my program.
This is how I'm reading the 8 bit binary number from the file
fd = open(argv[1], O_RDONLY);
read(fd,jString, 100);
close(fd);
printf("jString: %s\n", jString);
Right now I only know how to put the 8 bit binary number into a string but what I want is to turn each 8 bit binary number input separated by spaces from the file into an argument char* argv[] for my program is this possible if so how do I do it?
Something that I already tried is this.
fd = open(argv[1], O_RDONLY);
read(fd,argv[1], 100);
the problem with this is that it just reads the whole file into argv[1] and doesn't seperate them by spaces and into different arguments for my program.
What I'm having trouble with is getting the 8 bit binary number from a
file and making that an argument char* argv[] for my program
You can not do this. The usual declaration of
int main(int argc, char** argv){};
means that these 2 arguments are provided for you by the operating system when your program is run. What you can do is build something like this for your program, let's say a int myArgCountand char** myArgValues; but it seems that you do not need that.
If task is you program, running task 00001111 will put 00001111 into argv[1]. And set argcto 2, since argv[0] is always the complete path of your program.
At first you say that a binary number can be provided in a file, but in the next paragraph you said
what I want is to turn each 8 bit binary number input separated by spaces
If in fact the input file can have a list of 8-bit binary numbers separated by spaces --- and not just one --- you will need do build a list just like the system does for you, alocating memory for the numbers and creating an array of pointers to them, and an int with the count of numbers. It is not complicated.
The code below tests for an argument on the command line and if not present tries to open source.txt file to get one. May be it helps.
Note the use of scanf()to read the values from the file. The mask in use "%8[01]" is very convenient: it accepts just 0 and 1 for a maximum of 8 digits.
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
int main(int argc, char** argv)
{
char binary_number[10];
char* mask = "%8[01]"; // for scanf()
const char* FileName = "source.txt";
if (argc < 2)
{ // no number on the command line
fprintf(stderr, "\nNo 8-bit number provided on the command line\n");
FILE* in_file = fopen(FileName, "r");
if (in_file == NULL)
{
fprintf(stderr, "Could not open [%s]\n", FileName);
return -1;
}
int n = fscanf(in_file, mask, binary_number);
printf("\nFrom the file [%s] number is [%s]\n", FileName, binary_number);
fclose(in_file);
}
else
{ // number provided
strncpy(binary_number, argv[1], 9);
fprintf(stderr, "\nFrom the command line: [%s]\n", argv[1]);
};
return(EXIT_SUCCESS);
};
the program shows
From the command line: [101010]
or
No 8-bit number provided on the command line
From the file [source.txt] number is [11110000]
here your program with dynamic memory allocation:
Argument separtor = ' '
Argument from commande = your_program_name "10001010" "01010101"
Argument from file : command-line = your_program_name "...\yourfile.xyz" Example :
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#define DELIMITER ' '
// Tokenize function
int Tokenize(char* pcLine, char ** pcListeArgs, const char* pcDelim)
{
int iNumElet = 0;
size_t len = 0;
// Get line size
int init_size = strlen(pcLine);
char *ptr = strtok(pcLine, pcDelim);
while(ptr != NULL)
{
len = strlen(ptr);
pcListeArgs [iNumElet] = (char*) calloc (len+1, sizeof (char));
memset(pcListeArgs [iNumElet], 0, len+1); // reset content
memcpy (pcListeArgs [iNumElet], ptr, len); // copy data
ptr = strtok(NULL, pcDelim);
iNumElet ++;
}
return iNumElet;
}
int main(int argc, char** argv)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
char ch;
char *pcFileContent;
char cDelim = DELIMITER;
// Case : argument are a file
if (argc == 2)
{
const char* pcFilePath = argv[1];
fp = fopen(pcFilePath, "r");
if (fp == NULL)
{
perror("Error while opening the file.\n");
return (-1);
}
// Put the curso at the end of file
fseek (fp,0, SEEK_END);
// Get number of charactes
len = ftell(fp);
// Allocat memory
pcFileContent = (char*) calloc (len+1, sizeof (char));
//Erase content to zero
memset(pcFileContent,'\0',len+1);
// Put the curso at the begining of file
fseek (fp,0, SEEK_SET);
// Read file char by char
unsigned int i=0;
unsigned int iNbArgs = 1;
while((ch = fgetc(fp)) != EOF)
{
if (ch == DELIMITER)
iNbArgs ++; // We have a new arguments
pcFileContent[i++] = ch;
}
char **pcListeArgs = (char**) calloc (iNbArgs, sizeof (char*));
iNbArgs = Tokenize (pcFileContent, pcListeArgs, &cDelim);
// here you have all you arguments ....
for ( i=0; i< iNbArgs; i++)
{
printf ("Argument %d = %s\n", i, pcListeArgs[i]);
}
// Free memory
for(int i = 0; i < iNbArgs; i++)
free(pcListeArgs[i]);
free(pcListeArgs);
free(pcFileContent);
}else if ( argc > 2) // Case : argument is binary number
{
for ( int i=1; i< argc; i++)
{
printf ("Argument %d = %s\n", i, argv[i]);
}
}
return 0;
}
Result:
Argument from commande = ArgParsor.exe "10001010" "01010101" "01010111"
Argument from file : command-line = ArgParsor.exe "G:\temp.txt"
I have an binary array and i am trying to convert this into a single variable so that i can read the binary bitwise consecutively. I have tried looping over the array and adding each of them into a variable but this has not work. Can anyone give me some pointers into how to do this?
This is what i have tried:
char* filename = vargs[1];
BYTE buffer[BUFFER_SIZE];
FILE *file_ptr = fopen(filename,"rb");
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
fread(buffer, sizeof(BYTE), BUFFER_SIZE, file_ptr);
char binaryLine = '\0';
for (int i = 0; i > file_length; i++)
{
binaryLine += buffer[i];
printf("%d ", (int)buffer[i]);
}
Maybe there is some miss understanding, but when you read a file in a char* or char[], that is one variable.
Maybe try below code, and see what your missing.
Pay attention to, just to name a few:
for instruction, need to be true to continue
fread you need to get the amount of bytes read to loop it
main, it's a function or it's main, show it
fopen etc, would also neeed you to check for errors, which might help you to figure out why something does not work
regarding your question, It's important to ask a question and provide info, as stated in other comment, what do you want....
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
const char* filename = argv[1];
char * buffer=NULL;
FILE *file_ptr = fopen(filename,"rb");
if (! file_ptr) return 1;
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
if (file_length!=0)
buffer=calloc(1,file_length);
if (buffer)
{
size_t bytes_read=fread(buffer, 1, file_length, file_ptr);
for (int i = 0; i < bytes_read; i++)
{
printf("%d ", (int)buffer[i]);
}
free(buffer);
buffer=NULL;
return 0;
}
return 1;
}
I have an assignment to write a program that copies takes 2 arguments (filePaths) and copies the first file into the second.
As far as I can tell, I should I'm supposed to use fgets.
What I have seems to work, up until the end when I can't get detect the end of the file. According to everything I've read, it seems like fgets is supposed to stop when it hits the end of the file and return null or something, but if I let it this keeps reading the last line of the file.
Here's the code. I don't want answers (this is homework), I just want to understand what I'm doing, so I can get the answer myself:
#include <stdio.h>
#define BUFFER_SIZE 80
int readLineFromFile(FILE* file, char* buffer) {
if(! *fgets(buffer, BUFFER_SIZE, file)) {
return -1;
}
int length;
for(length=0; buffer[length] != '\0'; length++);
return length;
}
void writeLineToFile(FILE* file, char* buffer) {
fprintf(file, "%s", buffer);
}
int main(int argc, char **argv) {
if (argc != 3) {
printf("incorrect number of arguments, 2 text files expected, recieved %d\n", argc - 1);
return 0;
}
FILE* input = fopen(argv[1], "r");
FILE* output = fopen(argv[2], "w");
char buffer[BUFFER_SIZE];
int charsRead = readLineFromFile(input, buffer);
int i;
while(0 < charsRead) {
writeLineToFile(output, buffer);
charsRead = readLineFromFile(input, buffer);
printf("%d\n", i++);
}
fclose(input);
fclose(output);
return 0;
}
I think the problem is with the function dereferencing in if(! *fgets(buffer, BUFFER_SIZE, file)) {. I changed *fgets to fgets and it ran fine. See the correct code here. But for extra credit, figure out how to make this work with any filetype, not just plaintext.
I am trying to write a program that takes the words from a file, and puts those in a dynamic array. However when I try to run my code the program copies it all except for the spaces. How do I fix this?
This is a test does it work?
But I get the following:
Thisisatestdoesitwork?
char** getWords(char* filename, int* pn){
char** tmp = (char**)malloc( 1000*sizeof(char));
int *temp=(int*)malloc(1000*sizeof(int);
int c;
int counter = 0;
FILE* fileInput = fopen(filename, "r");
if(fileInput == NULL){
return tmp; // return if file open fails
}
while((c=fgetc(fileInput)) != EOF){
result = fscanf(fileInput, "%c", &c); //try to read a character
if(isalpha(c)){ //chararect alphabetical
tmp[counter] = c; // safe int to array
counter ++;
printf("%c", c); fflush(stdout);
}
else{ // if read not succesfull
fscanf(fileInput, ""); // needs to scan anything not a character
}
if(counter > 100){ // to not exceed the array
break;
}
if(feof(fileInput)){ // to check if at the end of the file
break;
}
}
fclose(fileInput); // closing file
*pn = counter;
return tmp;}
My main Function:
int main(int argc, char* argv[]){
int n;
char** a = getWords("opdracht_4_5.c", &n);
if (a != NULL){
puts("gevonden woorden:");
for (int i = 0;i < n; i++){
printf("%3d %s\n",i,a[i]);
}
for (int i = 0;i < n; i++){
free(a);
}
free(a);
}
return (EXIT_SUCCESS);
}
There are quite a few problems with your code. Here's a start:
You don't test the return value of fopen().
You don't test the return value of malloc().
You assign the return value of fgetc() to a variable of type char. Plain char is compatible with either signed char or unsigned char. In order to make a distinction between a character and EOF (which is negative), the fgetc() function returns a character converted to unsigned char (or EOF). You need to test for EOF and then convert the value to a plain char.
The is...() function expects an int argument whose value is in the range of an unsigned char or EOF. If you have a plain char, you first have to cast it to unsigned char, or you can pass the return value of fgetc() straight to isalpha().
You attempt to append an zero-length char array (temp) to an uninitialized char array (s), and you do not test if there is enough room in the target array. This is broken for more reasons than than I care to enumerate.
You allocate memory for an array of 1000 pointers to char, but you never allocate memory for the char pointers themselves.
You try to append your buffer (s) to an uninitialized pointer (*tmp).
You call strlen() on something that is not null-terminated.
You never return the length of the array.
You call a number of functions that have not been declared.
This will read the file, put each word in an array
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char** getWords(char* filename, int* pn){
char input[100]; // array to hold each word
char** tmp; // double pointer
int counter = 0;
int words = 0;
int c;
tmp = malloc( (*pn)*sizeof(char*)); // allocate pointers for number of words
if ( tmp == NULL) {
printf ( "malloc failed\n");
exit (1);
}
FILE* fileInput = fopen(filename, "r");
if(fileInput == NULL){
printf ( "file open failed\n");
*pn = 0; // no words entered
return tmp; // return if file open fails
}
while(( c = fgetc(fileInput)) != EOF){
if( isalnum(c)){ // is alpha or number
input[counter] = c; // save to array
input[counter + 1] = '\0'; // save a \0 to the end to make a string
counter ++;
}
else{ // not alpha or number
if ( counter > 0) { // if there are characters, save the word
tmp[words] = malloc ( strlen ( input) + 1); // memory for this word
strcpy ( tmp[words], input); // copy the word to the array
words++;
counter = 0;
if ( words >= *pn) { // got all the words wanted
break;
}
}
}
if(counter > 98){ // too many characters for input, start a new word
tmp[words] = malloc ( strlen ( input) + 1);
strcpy ( tmp[words], input);
words++;
counter = 0;
if ( words >= *pn) {
break;
}
}
}
fclose(fileInput); // closing file
*pn = words; // save number of words
return tmp;
}
int main(int argc, char* argv[]){
int n;
int i;
printf ( "enter the number of words to obtain\n");
scanf ( "%d", &n);
char** a = getWords("opdracht_4_5.c", &n);
if (a != NULL){
puts("gevonden woorden:");
for ( i = 0;i < n; i++){
printf("%3d %s\n",i,a[i]);
}
for ( i = 0;i < n; i++){
free(a[i]); // free each word
}
free(a); // free the pointer to the words
}
return (EXIT_SUCCESS);
}
The input file I used had these as the first two lines
#include<stdio.h>
#include<string.h>
I get this output:
enter the number of words to obtain
6
gevonden woorden:
0 include
1 stdio
2 h
3 include
4 string
5 h
This answer is as yet incomplete
Please allow me to finish this before commenting on it -- Thank you
There are a lot if issues with your code, I won't clean it up for you. However I would like to give you some hints on how your program SHOULD be coded:
Your main objective is to read a file and load the content word by word in an array.
Sorting is an incorrect use because that implies you want to sort them alphabetically or in some other order after loading it into an array.
Okay, so first things first, let's figure out the overall operation of our program. We'll call our program kitten, because it's not quite as powerful as cat.
To run our program we will assume that we give it the filename we want to read on the command-line as follows:
$ ./kitten somefile.txt
and expect the output to be:
word1
word2
word3
.
.
.
wordN
Total words: N
So, let's get started, first we make sure that our user specifies a filename:
#include <stdio.h>
int usage(const char *progname);
int main(int argc, char *argv[])
{
if (argc < 2) {
usage(argv[0]);
return -1;
}
return 0;
}
int usage(const char *progname)
{
fprintf(stderr, "Usage is:\n\t%s filename\n", progname);
}
Now that we know that our program can get a filename, let's try to open the text file, if there is an issue with it we use perror to display the error and exit the program, otherwise we are ready to use the file:
#include <stdio.h>
#include <errno.h>
int usage(const char *progname);
int main(int argc, char *argv[])
{
FILE *fp;
if (argc < 2) {
usage(argv[0]);
return -1;
}
fp = fopen(argv[1], "r");
if (!fp) {
perror(argv[1]); /* display system error, with the filename */
return -1;
}
/* TODO: file manipulation goes here */
fclose(fp); /* close the file */
return 0;
}
int usage(const char *progname)
{
fprintf(stderr, "Usage is:\n\t%s filename\n", progname);
}
Now in C each function should perform just one task. The task should make human sense. For example if the function is supposed to read words into an array, then that's all it should do, it should not open a file or close a file, which is WHY the code above does not create a function for opening the file the way you did. Your function should take in FILE * as the file to read.
Because we use the FILE * as input we'll start the function name with an f to keep with the stdio convention. Ideally, the function should take a pointer to char * (strings) to store the words in.
#include <stdio.h>
#include <errno.h>
int usage(const char *progname);
size_t fload(FILE *fp, char **wordlist_p);
int main(int argc, char *argv[])
{
FILE *fp;
if (argc < 2) {
usage(argv[0]);
return -1;
}
fp = fopen(argv[1], "r");
if (!fp) {
perror(argv[1]); /* display system error, with the filename */
return -1;
}
if(fload(fp, wordlist_p) < 0) {
fprintf(stderr, "Something went wrong\n")
}
fclose(fp); /* close the file */
return 0;
}
int usage(const char *progname)
{
fprintf(stderr, "Usage is:\n\t%s filename\n", progname);
}
size_t fload(FILE *fp, char **wordlist_p)
{
size_t rv = -1; /* return value */
return rv;
}
Now we run into a conceptual problem. How do we allocate memory for wordlist_p? I mean we don't have any idea about how big the file is, we also don't know how big the biggest word in the file is.
Crude approach
Let's first try an think about it the simple way:
Point to the beginning of the `wordlist_p` with a `tail_pointer`
Read the file line by line, (we assume no hyphenation)
For each line split the line up along white spaces,
Allocate space for the number of words in the `wordlist_p` array
For each word in the split line
Allocate space for the word itself
Save the pointer to the word at the tail_pointer
Advance wordlist_p tail_pointer
Next word
Next Line
Let's look at what the fload function would look like with these steps above,
More to come ##
I have the following code that converts a stream data of 16-bit integer to unsigned 8-bit integer.
I am looking to convert them to alphabetical data values and see what they contain.
#include<stdio.h>
int main() {
FILE *fp,*out;
char buffer[256];
size_t i = 0;
fp=fopen("c:/Gosam/input.txt", "rb");
if(fp != NULL) {
fread(buffer, sizeof buffer,1, fp);
}
out = fopen("c:/Gosam/res.txt", "w");
if(out != NULL) {
// buffer = (char*) malloc (sizeof(char)*Size);
for( i = 0; i < sizeof(buffer); i += 2)
{
const unsigned int var = buffer[i] + 256 * buffer[i + 1];
fprintf(out, "%u\n", var);
}
fclose(out);
}
fclose(fp);
}
The following is the form of my output:
263 4294966987 4294967222 4294967032 64 4294967013 73 4294967004 90
4294967028 83 4294966975 37 4294966961 5 4294966976 82 4294966942
4294967022 4294966994 11 4294967024 29 4294966985 4294966986 4294966954 50
4294966993 4294966974 4294967019 4294967007
This are the values I want to convert to alphabetical characters and see their content.
I don't know what you expect as an answer (you didn't ask a question), but there seems to be one suspicious thing in your code:
char buffer[256];
Here char means signed char. If your code does manipulations on them (like multiplying by 256), it probably doesn't do what you expect (though I can only guess what you expect - your question doesn't mention it).
Try the following:
unsigned char buffer[256];
Also please ask a question (that is, something with a question mark), and give some examples (input, output).
Your basic mistakes were:
after opening the inputfile checking out instead of fp against NULL
fread until eof won't return the number of characters that could be read (I've used fseek and ftell for this purpose)
writing uint values instead of char values to your file
I've fixed them and commented the affected lines appropriate. I also changed the buffer to use dynamic memory allocation instead of static allocation (that's how you can allocate memory for a buffer of a size that is unknown at compile-time). Please try the following code, which will copy all ASCII characters from one file to your output file (which is probably what you meant by 'alphabetical strings'):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]){
FILE *fp, *out;
char *buffer = NULL; /* use a pointer for dynamic memory allocation */
size_t i = 0, charCount = 0;
fp = fopen("c:/input.txt", "r"); /*read as ascii - not binary */
if(fp != NULL){ /*use 'fp' here 'out' is not initalized */
fseek(fp, 0, SEEK_END); /* go to end of the file */
charCount = ftell(fp) - 1; /* get position */
fseek(fp, 0, SEEK_SET); /* return to the beginning of the file */
buffer = (char*)malloc(sizeof(char)*charCount); /* allocate memory */
fread(buffer, sizeof(char) * charCount, 1, fp); /* reads all characters from the file */
}
out = fopen("c:/output.txt", "w");
if(out != NULL){
for(i = 0; i < charCount; i += 1){ /* loop from 0 to count of characters */
const unsigned char var = buffer[i];
fprintf(out, "%c", var);
}
fclose(out);
}
fclose(fp);
if(buffer != NULL){
free(buffer); /* deallocate memory */
}
return 0;
}