The API's that I am supposed to to use for this are open(), write() and sprintf(). If you are going to post a response of answer please don't recommend any other API's.
My program is supposed to scan for 10 elements and then print the elements in reverse order to the terminal and to a txt file.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <err.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int fd;
char buffer[100];
int *arr;
int i;
arr = malloc(10 * sizeof(int));
fd = open("file.txt", O_WRONLY | O_CREAT, 0644);
if (fd < 0)
{
perror("write() failed\n");
exit(-1);
}
printf("Input 10 elements in the array:\n");
for(int i = 0; i < 10; i++){
scanf("%d", &arr[i]);
}
printf("\nElements in array are: ");
sprintf(buffer, "Elements in array are: ");
// write(fd, buffer,strlen(buffer));
for(int j=9; j>=0; j--){
//print to console
printf("\n%d ", arr[j]);
sprintf(buffer,"\n%d", arr[i]);
}
//write to file
write(fd, buffer,strlen(buffer));
close(fd);
free(arr);
printf("\n");
return 0;
}
The elements of the array print in reverse order to the terminal perfectly fine. The area I am stuck on is printing it to a text file. I know how to use fprintf() and writing to a text file with that API but right now my instructions are to use open() and write(). In my text file I have the following:
1
My question is what can I do to fix this and get the correct output in the txt file. Thanks.
I tried the above code.
In this for loop
for(int j=9; j>=0; j--){
//print to console
printf("\n%d ", arr[j]);
sprintf(buffer,"\n%d", arr[i]);
}
each element of the array arr is being written in the beginning of buffer overwriting the previous content of buffer.
Instead you could write for example
int offset = 0;
for(int j=9; j>=0; j--){
//print to console
printf("\n%d ", arr[j]);
offset += sprintf(buffer + offset,"\n%d", arr[i]);
}
In this case each next element of the array will be appended to the string already stored in buffer.
Here is a demonstration program.
#include <stdio.h>
int main( void )
{
int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( arr ) / sizeof( *arr );
char buffer[100];
int offset = 0;
for (size_t i = N; i != 0; )
{
offset += sprintf( buffer + offset, "\n%d", arr[--i] );
}
puts( buffer );
}
The program output is
9
8
7
6
5
4
3
2
1
0
Another approach is to move this statement
write(fd, buffer,strlen(buffer));
inside the for loop.
Related
Hello, my question is: How to print out string 1 and string 2, not only string 2. I am new to dynamically memory allocated. My sample code is below, thanks for your help.
Result expected:
Hello
My name is Ken
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
int n, i;
char *ptr;
printf("How many strings you want to display?: ");
scanf("%d", &n);
ptr = (char*)malloc(n * sizeof(n));
if(ptr == NULL){
printf("Failed to allocate the memory to string!\n");
exit(0);
}
for(i = 0; i < n; i++){
printf("String %d: ", i + 1);
fflush(stdin);
scanf("%[^\n]", ptr);
}
printf("\n");
printf("Strings you entered:\n");
for(i = 0; i < n; i++){
printf("%s\n", ptr);
}
}
Please check the below code. I have marked modified lines with a comment starting with // CHANGE.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// CHANGE - free memory when not needed
void free_memory(char** ptr, int n)
{
if (ptr)
{
int i;
for (i = 0; i < n; i++)
{
if (ptr[i])
{
free(ptr[i]);
}
}
free(ptr);
}
}
int main(){
int n, i;
char **ptr; // CHANGE - make a double pointer - array of strings (imagine rows and columns)
printf("How many strings you want to display?: ");
scanf("%d", &n);
ptr = (char**) malloc(n * sizeof(char*)); // CHANGE - allocate memory based on no. of rows (columns are string characters)
if (ptr == NULL) {
printf("Failed to allocate the memory to string!\n");
exit(1);
}
getchar(); // CHANGE - read the newline character else fgets doesn't work
for (i = 0; i < n; i++) {
ptr[i] = (char*) malloc(256 * sizeof(char)); // CHANGE - allocate memory for each row
printf("String %d: ", i + 1);
if ( fgets(ptr[i], 256 * sizeof(char), stdin) == NULL ) {
printf("Failed to get line input\n");
free_memory(ptr, n);
exit(1);
}
ptr[i][strlen(ptr[i]) - 1] = '\0'; // CHANGE - remove extra newline character at the end
}
printf("\n");
printf("Strings you entered:\n");
for (i = 0; i < n; i++) {
printf("%s\n", ptr[i]); // CHANGE - print each row
}
free_memory(ptr, n);
return 0;
}
First, there are two numbers that should be decided:
the number of strings the user wants to input and
the length of the strings (or the lengths of each string).
Each string will be stored in a char*. And all strings together will be stored in a char**. The length of char** will be your n in this case.
And length of each char* can be decided however you want.
I prefer to use a directive #define to define a constant like 100.
You can also do a global or local variable or just a digit.
Also don't forget to free anything you allocate. Check below for details.
And happy coding!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STRING_SIZE 100
int main(){
int n, i;
// stores all the strings
char **ptr;
printf("How many strings you want to display?: ");
scanf("%d", &n);
// allocate memory of size (n * size of char*)
ptr = (char**)malloc(n * sizeof(char*));
if(ptr == NULL){
printf("Failed to allocate the memory to string!\n");
// for portability to use EXIT_FAILURE,
// which is defined in the standard library
exit(EXIT_FAILURE);
}
// for each pointer, allocate memory of size (MAX_STRING_SIZE * size of char)
for(i = 0; i < n; i++)
// I should put a validity check here but I'm too lazy...
ptr[i] = (char*)malloc(MAX_STRING_SIZE * sizeof(char));
for(i = 0; i < n; i++){
printf("String %d: ", i + 1);
fflush(stdin);
scanf("%[^\n]", ptr[i]); // use ptr[i]
}
printf("\n");
printf("Strings you entered:\n");
for(i = 0; i < n; i++){
printf("%s\n", ptr[i]); // use ptr[i]
}
// free all of them
for(i = 0; i < n; i++)
free(ptr[i]);
free(ptr);
return 0;
}
So I have this program where it asks the user for a filename to read, and a filename to save the output to. This program basically counts the frequency of a letter inside the txt file. Here is the program...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char letter[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", FileName[50], SaveFile[50], print[256], stry[50], scount[50], point;
int i, j, count = 0;
FILE * readFile, *saveFile;
printf("Enter a file to read: ");
gets(FileName);
printf("Enter a filename to save results: ");
gets(SaveFile);
printf("Letter Frequency\n\n");
saveFile = fopen(SaveFile, "wb");
for(i = 0; i <= strlen(letter)-1; i++)
{
readFile = fopen(FileName, "r");
while(!feof(readFile))
{
fgets(print, 256, readFile);
for(j = 0; j <= strlen(print); j++)
{
if(toupper(print[j]) == toupper(letter[i]))
{
count++;
}
}
point = letter[i];
stry[0] = point;
sprintf(scount, "%d", count);
if(feof(readFile) && count > 0)
{
printf("%s %d\n", stry, count);
fprintf(saveFile, stry);
fprintf(saveFile, " ");
fprintf(saveFile, scount);
fprintf(saveFile, "\n");
}
}
count = 0;
}
fclose(readFile);
return 0;
}
I input a txt file named readme.txt that I modified. It contains
aaa
bbb
ccc
ddd
But when I run it, and used readme.txt to be read, the output is
A 3
B 3
C 3
D 6
The frequency of letter D must be only 3. I further modified the content of the readme.txt file, and figured out that value of the variable count is doubled when reading the last line. For example, the content of the txt file is
hello mama
hihihi
maria maria
woohoo
the output will be
A 6
E 1
H 6
I 5
L 2
M 4
O 9
R 2
W 2
I read my program so many times already, and I still can't find my wrong doings. I hope you can help me fix this problem. Your help will be very much appreciated!
EDIT:
This is what my code looks like after making the changes that were recommended in the comments section:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char letter[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", FileName[50], SaveFile[50], print[256], stry[50], scount[50], point;
int i, j, count = 0;
FILE * readFile, *saveFile;
printf("Enter a file to read: ");
gets(FileName);
printf("Enter a filename to save results: ");
gets(SaveFile);
printf("Letter Frequency\n\n");
saveFile = fopen(SaveFile, "wb");
for(i = 0; i < strlen(letter); i++){
readFile = fopen(FileName, "r");
while(fgets(print, 256, readFile) != NULL)
{
fgets(print, 256, readFile);
for(j = 0; j <= strlen(print); j++)
{
if(toupper(print[j]) == toupper(letter[i]))
{
count++;
}
}
point = letter[i];
stry[0] = point;
sprintf(scount, "%d", count);
if(feof(readFile) && count > 0)
{
printf("%s %d\n", stry, count);
fprintf(saveFile, stry);
fprintf(saveFile, " ");
fprintf(saveFile, scount);
fprintf(saveFile, "\n");
}
}
count = 0;
}
fclose(readFile);
return 0;
}
I tried to print integer value, But It's print only result is
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++){
if(i % 2 == 0){
printf("result is \n","%d",i);
}
}
return 0;
}
I tried this way. It's not print anything
int main()
{
char buffer[10];
for (int i = 0; i < 10; i++){
if(i % 2 == 0){
snprintf(buffer, sizeof(buffer), "%d", i);
}
}
return 0;
}
%d should not be a separate parameter to printf but part of the template.
Try
printf("result is %d\n",i);
With your second example, you use:
snprintf(buffer, sizeof(buffer), "%d", i);
It works by wiring the integer as a string to your buffer char array, not to the console (as per documentation).
Adding the line after the snprintf line:
printf("%s\n", buffer);
You could print the content of your buffer to the screen.
I want to have unknown amount of inputs in a single line. For example, user can input:
"ans: 1 2 3 4 5"
and scanf() will store these five numbers to an array. The problem is that the program don't know how many input will there be.
#include <stdio.h>
int main()
{
int i;
int input[4];
scanf("ans: " for(i = 0, i < 3,i++){scanf(" %d", &input[i]);};
return 0;
}
Sorry I'am totally new to coding, what will be the proper way to write this? Or is this impossible?
Thanks :)
Use fgets() and sscanf() with "%n"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char input[100];
int arr[10];
//fgets(input, sizeof input, stdin);
strcpy(input, "1 2 42 56 -3 0 2018\n"); // fgets
char *pi = input;
int tmp, pp, i = 0;
while (sscanf(pi, "%d%n", &tmp, &pp) == 1) {
if (i == 10) { fprintf(stderr, "array too small\n"); exit(EXIT_FAILURE); }
pi += pp;
arr[i++] = tmp;
}
printf("got this ==>");
for (int k = 0; k < i; k++) printf(" %d", arr[k]);
puts("");
}
You asked this question way round.
You can achieve what you expect by putting scanf inside of a loop.Even you can ask user to give how many inputs he want to enter.
#include <stdio.h>
int main()
{
int i;
int input[4];
printf("Enter the number of inputs you want to give : ");
scanf("%d", &n);
for(i = 0; i < n;i++)
{
printf("Enter the input number %d : ",i);
scanf("%d", &input[i]);
}
return 0;
}
I've printed a string of "+" symbols based on two given values(N, M). Now I'm trying to figure out how to replace characters at random in said string based on a third given value(K). The characters are stored in a string(l). I think I have to use the replace function but I don't know how(hence why it's in a comment for now). Any help is appreciated.
#include <stdio.h>
unsigned int randaux()
{
static long seed=1;
return(((seed = seed * 214013L + 2531011L) >> 16) & 0x7fff);
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char s[1000];
int N, M, K, l;
printf("N: ");
scanf("%d",&N);
printf("M: ");
scanf("%d",&M);
printf("K: ");
scanf("%d",&K);
printf("\n");
gets(s);
l=strlen(s);
/* Mostre um tabuleiro de N linhas e M colunas */
if(N*M<K){
printf("Not enough room.");
}else if(N>40){
printf("Min size 1, max size 40.");
}else if(M>40){
printf("Min size 1, max size 40.");
}else{
for(int i=0; i<N; i++)
{
for(int j=0; j<M; j++)
{
printf("+", s[j]);
}
printf("\n", s[i]);
}
for(int l=0; l<K; l++)
{
/*s.replace();*/
}
}
return 0;
}
There is too much unexplained complexity and unknowns in your program to enable a corrective answer. But this shows how to replace a textual string's character at random, with a numeral.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(void)
{
char str[] = "----------";
int len = strlen(str);
int index;
int num;
srand((unsigned)time(NULL)); // randomise once only in the program
printf("%s\n", str); // original string
index = rand() % len; // get random index to replace, in length range
num = '0' + rand() % 10; // get random number, in decimal digit range
str[index] = num; // overwrite string character
printf("%s\n", str); // altered string
return 0;
}
Program sessions:
----------
-3--------
----------
-----0----
----------
--------6-
Arguably it would be better to use size_t types, but for the limited range of the example, will suffice.