Print and Clear in C without libraries [closed] - c

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 5 years ago.
Improve this question
I'm trying to develop a Operative System.
It works, but the function "print" that I've written has an error:
If I print two Strings only one will be displayed, and the command \n does not work.
My questions are:
How to use the command \n?
and
How to create the function clear without using libraries?
This is the function print:
void print(char* message, int color)
{
char* mem = (char*)(0xb8000);
while(*message != 0)
{
*mem = *message;
mem++;
message++;
*mem = (char*)color;
mem++;
}
}
PS It Works, but the problem is that if I use the function print two times (with or whitout \n it prints me only the second part.

To simulate a line break you probably need to write as many spaces to the video memory as there are characters left in the current line. Hence, you need to remember how many characters you wrote to the current line.
The same applies for scrolling. You need to copy the memory in a way that the last line on the screen becomes blank again.

You should have some context of the printing function.
eg: you should have a global(or static) variable to remember your last printed position of the video output memory.
something like:
```
static int last_pos = 0;
void print(char* message, int color)
{
char* mem = (char*)(0xb8000);
mem += last_pos * 2;
while(*message != 0)
{
if(*message == '\n') {
set the mem to next line and calculate the new last_pos
continue;
}
*mem = *message;
mem++;
message++;
*mem = (char*)color;
mem++;
last_pos ++;
if (last_pos >= max_video_buffer) {
move content the buffer to scroll the screen
or
simply reset the last_pos and mem to restart from top-left.
}
}
}
```
when do clearing: just fill the whole video output memory to empty and reset the last_pos

Related

Is "segmentation fault" caused from fopen line a stack overflow problem in C? (darknet, detector.c) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
I am experiencing a darknet YOLOv4. I want to add detection result logging line to this mAP example code.
I think I wrote a line that writes files according to the grammar, but the "segmentation fault" error occurs in the line where "fopen" is operated.
The line like printf works well.
The validate_detector_map() part of the detector.c of darknet is attached below.
https://github.com/AlexeyAB/darknet/blob/master/src/detector.c#L940
And below is the part I added.(////ju added~ //////////)
... // For multi-class precision and recall computation
float *avg_iou_per_class = (float*)xcalloc(classes, sizeof(float));
int *tp_for_thresh_per_class = (int*)xcalloc(classes, sizeof(int));
int *fp_for_thresh_per_class = (int*)xcalloc(classes, sizeof(int));
for (t = 0; t < nthreads; ++t) {
args.path = paths[i + t];
args.im = &buf[t];
args.resized = &buf_resized[t];
thr[t] = load_data_in_thread(args);
}
////ju added //파일 열려야 하는 위치
printf("\nlogging start.. \n\n");
FILE *log_csv;
printf('%d\n', fileno(log_csv));
if(!(fopen("/home/aicar/darknet/0_log_ju0.csv", 'a')))
{
printf("failed to open csv file\n\n");
exit(1);
}
else
{
printf("csv file opened\n\n");
fprintf(log_csv, "timestamp, class_id, gt, conf_mat, \n" ); //header row
fclose(log_csv);
}
//////////
time_t start = time(0);
for (i = nthreads; i < m + nthreads; i += nthreads) { ......
Is this a stack overflow problem? The reason I thought that was because the author used the free function.
fopen returns a file handle. Just a couple lines above you're defining a variable FILE *log_csv; which would be probably where you want to put that handle.
Furthermore the second argument of fopen is a C-string (i.e. a pointer to a NUL terminated array of chars). TTBT, I'm surprised your compiler did let this pass.
Try this:
FILE *log_csv = fopen("/home/aicar/darknet/0_log_ju0.csv", "a");
if( !log_csv ){
printf("failed to open csv file\n\n");
exit(1);
} else {
printf("%d\n", fileno(log_csv));
…
}
This code is also dangerous:
FILE *log_csv;
printf('%d\n', fileno(log_csv));
The fileno() function will attempt to dereference log_csv, which does not point to a FILE structure and therefore extremely likely to cause a SIGSEGV crash.

C about words reverse [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I tried to use C array to write about the code below.
When I entered=>I am a boy.
The desired output is=>boy a am I.
Here is my code below and it does not work.
I have found the bugs for 2 days and I still could not find the problem
int i,j,k,m,start,temp_end,len;
char str[30];
gets(str);
len=strlen(str);
temp_end=len-1;
for(k=len;k>0;k--)
{
if(str[k]==" ")
start=k;
for(j=start+1;j<temp_end;j++)
{
printf("%c",str[j]);
}
printf(" ");
temp_end=k;
}
for(m=0;m<temp_end;m++)
{
printf("%2c.",str[m]);
}
As others have pointed out there are multiple problems with your code.
In the condition if(str[k]==" "), you are using " " to represent a single space character, which is incorrect. For a single space character you need to use ' '. A " " is a string with a single space character.
You are running the for(j=start+1;j<temp_end;j++) { … } loop every time. However this should be run only when a new space, ' ' is found. You can use a flag for this. Same with printf(" ");, and temp_end = k;
printf("%2c.", str[m]) looks to be like a typo. Why %2c.? You should be doing just "%c".
/* Use a flag to know when to print */
/* 0 means don't print, 1 means print */
int pflag = 0;
for(k = len-1; k >0; k--)
{
if(str[k]==' ') {
pflag = 1; /* new space found, update the flag to print */
start=k;
}
if (pflag == 1) /* check flag to see if print needed */
{
for(j=start+1;j<temp_end;j++)
{
printf("%c",str[j]);
}
printf(" ");
temp_end=k;
pflag = 0; /* reset flag after printing */
}
}
for(m=0;m<temp_end;m++)
{
printf("%c",str[m]);
}
Also, do NOT use gets(). Use fgets() or something else.

Command line arguments using if/else statements in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am new to programming and this one has me baffled.
I am writing a function to be called by main that takes the command line arguments and stores them in a struct to use later. This specific example is for use with image editing, but can be used anywhere.
Desired performance: Function takes arguments from the command line. Three specific arguments are identified and checked for: -h, -o and -t. If present they will alter the struct values. Arguments -o and -t store the arguments immediately following them into their respective struct fields. Any argument that is not -h or does not have -o or -t preceding it is assumed to be the input file name and stored in flag->inputFile. If all arguments are accounted for, then flag->inputFile should remain NULL and can be tested for in the main function and program terminated if this is true.
Problem: When there is no input file specified (using the above parameters) flag->inputFile keeps getting set to -o when it is included as an argument.
Solution: Thanks to Scott this question has been answered by replacing several if statements with else if has now seemed to fix the problem, and the function appears to be working as desired.
My understanding of what was happening is that the else statement was being run in every iteration of i unless the -t argument was included, since it was the statement immediately before the else
The compiler I'm using is gcc and this is my code. (I know my struct is not packed, I'm still trying to get my head around this and can't see how it would result in what I'm seeing. Segmentation fault, yes, but not this?)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct PROMPTFLAGS {
int help; // Change from NULL if -h argument present
char * outputFile; // Store argument after -o as the output file
char * inputFile; // Argument not paired with a flag stored here as input file
float threshold; // Stores a value to use in image manipulation in main
};
struct PROMPTFLAGS * parsargs(int argc, char * argv[]) {
struct PROMPTFLAGS* flag = malloc(sizeof(struct PROMPTFLAGS));
int i;
printf("argc: %d\n",argc);
for (i = 1; i < argc; i++) {
char * arg = argv[i];
int str_aft = i+1; // Allows the next string to be used in this iteration of the loop
if (strcmp(arg,"-h") == 0) {
flag->help = 1;
}
if (strcmp(arg,"-o") == 0) { // Changing this to 'else if' seems to be a fix
flag->outputFile = argv[str_aft];
i++; // Skips over next arg since already read by argv[str_aft]
}
if (strcmp(arg,"-t") == 0) { // Changing this to 'else if' seems to be a fix
flag->threshold = strtod(argv[str_aft],NULL);
i++; // Skips over next arg since already read by argv[str_aft]
}
else {
flag->inputFile = arg;
}
}
return flag;
}
int main(int argc, char* argv[]) {
struct PROMPTFLAGS * flags;
flags = parsargs(argc, argv);
printf("Help = %d\n",flags.help);
printf("Output = %s\n",flags.outputFile);
printf("Input = %s\n",flags.inputFile);
printf("Threshold = %s\n",flags.threshold);
return 0;
}
I apologise for the poor format of the first version of this question and hope that this edit is better. I have made the functions' desired outcomes and the problem I encountered clearer and removed most of the test prints I had through the code and added some comments. I have also included the solution to my problem (provided by another user) and my understanding of what was happening in the broken code.
If people still think this is a poor question or of no use to anyone else then I'm happy to take it down, but have edited and left it up hoping it can help someone else.
This is my first post on stack overflow and I thank everyone for their help and patience while I learn to code and the best manner to post questions.
You set flag->inputFile = arg whenever arg is not "-t" (the else after testing for "-t"). I'm not sure when you want to assign to this field, but I am sure this isn't the right logic for it. For example, if you wanted to do this when arg is none of the other specific flags you are looking for, you should be using if ... else if ... else if ... else.

C hack: replace printf to collect output and return complete string by using a line buffer [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
Got this great C program I'd like to embed into an iOs app.
One passes command line arguments to it and the results are printed to stdout via printf and fputs - like with all the good old unix programs.
Now I'd like to just edit main and the print functions to use my own printf function which collects all the output that normally goes to stdout and return it at the end.
I implemented a solution by using a line buffer to collect all the printfs until the newline.
And a dynamic char array whereto I copy when an output line is finished.
The charm of this solution is - it's kind of tcl'ish: just throw everything into a text line and if its complete store it. Now do that as long as necessary and return the whole bunch at the end ...
And here the question:
It works - but as I am fairly new in "real" programming - i.e. C and Apples "brandnew" Swift - am not sure wheter this is a good solution. Is it? And if not - what would you suggest? Thank you very much!
Here follows the C code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
// outLineBuffer collects one output line by several calls to tprntf
#define initialSizeOfReturnBuffer 10 // reduced for testing (would be 16*1024)
#define incrSizeOfReturnBuffer 5 // reduced for testing (would be 1024*1024)
#define outLineBufferMaxSize 4095
char outLineBuffer[sizeof(char)*outLineBufferMaxSize] = "";
char *tReturnString;
size_t sizeOfReturnBuffer, curPosOutBuffer = 0, lenOutLine = 0;
With the replacement tprntf for all the original printf and fputs:
// replace printf with this to collect the parts of one output line.
static int tprntf(const char *format, ...)
{
const size_t maxLen = sizeof(char)*outLineBufferMaxSize;
va_list arg;
int done;
va_start (arg, format);
done = vsnprintf (&outLineBuffer[lenOutLine], maxLen-lenOutLine, format, arg);
va_end (arg);
lenOutLine = strlen(outLineBuffer);
return done;
}
And the function when we complete one output line (everywhere \n is printed):
// Output line is now complete: copy to return buffer and reset line buffer.
static void tprntNewLine()
{
size_t newSize;
long remainingLenOutBuffer;
char *newOutBuffer;
remainingLenOutBuffer = sizeOfReturnBuffer-curPosOutBuffer-1;
lenOutLine = strlen(outLineBuffer)+1; // + newline character (\n)
remainingLenOutBuffer -= lenOutLine;
if (remainingLenOutBuffer < 0) {
newSize = sizeOfReturnBuffer + sizeof(char)*incrSizeOfReturnBuffer;
if ((newOutBuffer = realloc(tReturnString, newSize)) != 0) {
tReturnString = newOutBuffer;
sizeOfReturnBuffer = newSize;
} else {
lenOutLine += remainingLenOutBuffer; //just write part that is still available
remainingLenOutBuffer = 0;
}
}
snprintf(&tReturnString[curPosOutBuffer], lenOutLine+1, "%s\n", outLineBuffer);
curPosOutBuffer += lenOutLine;
outLineBuffer[0] = 0;
lenOutLine = 0;
}
And a little main to test it (without swift - e.g. plain gcc):
int main(int argc, char *argv[])
{
int i;
sizeOfReturnBuffer = initialSizeOfReturnBuffer*sizeof(char);
if ((tReturnString = malloc(sizeOfReturnBuffer)) == 0) {
return 1; // "Sorry we are out of memory. Please close other apps and try again!";
}
tReturnString[0] = 0;
for (i = 1; i < argc; i++) {
tprntf("%s ", argv[i]);
}
tprntNewLine();
tprntf("%s", "ABC\t");
tprntf("%d", 12);
tprntNewLine(); // enough space for that ;-)
tprntf("%s", "DEF\t");
tprntf("%d", 34);
tprntNewLine(); // realloc necessary ...
tprntf("%s", "GHI\t");
tprntf("%d", 56);
tprntNewLine(); // again realloc for testing purposes ...
printf("tReturnString at the end:\n>%s<\n", tReturnString); // contains trailing newline
return 0;
}
The call from swift will the be as follows (using CStringArray.swift)
let myArgs = CStringArray(["computeIt", "par1", "par2"])
let returnString = mymain(myArgs.numberOfElements, &myArgs.pointers[0])
if let itReturns = String.fromCString(returnString) {
print(itReturns)
}
freeMemory()
I am sure that tcl has many optimizations and I suggest you also optimize the code; then your approach can be viable.
Check your frequent use of strlen, which every time goes through all the (many) characters to count the length - use information about its length, for example maintain a char *outLineBufPtr. Also use strcat to append \n to outLineBuffer instead of using the expensive vsnprintf function, or just copy the char manually, as *outLineBufPtr++ ='\n'; .
To implement a higher-level concept such as yours, you must start thinking in machine cycles so the higher-level concept does not become "expensive".

adding of alternative node which contain interger value in give linked list? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Hi i wrote a code to add alternative node which contain integer value in single linked list.My code get crash please help me to fix it.
example lets take there are 6 node in singly linked list 3 5 8 6 4 9
then o/p should be 3+8+4 and 5+6+9 and my approach is wrong i guess please help me to fix it .In below code i am returning only one alternative value i.e 3+8+4 ?
void add(struct st **ptr)
{
struct st *curr,*prev;
curr=*ptr;
while(curr->next!=NULL)
{
if(curr->next->next->data!=NULL) //checking alternative node is present or
//or not and to avoid crash
{
sum= curr->data + curr->next->next->data;
}
else
{
sum= curr->data;
}
curr= curr->next;
}
prev=*ptr;
while(prev->next !=null)
{
prev=prev->next;
if(prev->next->next->data!=NULL)
{
sum=prev->data+prev->next->next->data;
}
else
{
sum=prev->data;
}
}
return sum;
}
First of all, It is not possible to return twice from a function. You can use call by reference as an alternative to it. Before the function call you can create two variables for two sums, initialize them to zero and send them as reference.
int sum_even = 0; //sum of elements at even position
int sum_odd = 0; //sum of elements at odd position
add(&start, &sum_even, &sum_odd); // call by reference
//sum_even and sum_odd will have the respective sums
Now for problem on linked lists it is advisable that you sit with pen and paper and try to trace each line of code you write. Testing boundary conditions is essential.
I have written a possible solution for your problem.
void add(struct st **ptr, int *sum_even, int *sum_odd)
{
struct st *even, *odd;
even = *ptr;
if(even->next) odd = even->next;
else odd = NULL;
while(even != NULL)
{
*sum_even += even->data;
if(even->next == NULL) break;
even = even->next->next;
}
while(odd != NULL)
{
*sum_odd += odd->data;
if(odd->next == NULL) break;
odd = odd->next->next;
}
}
if(curr->next->next->data!=NULL)
Here you should also check curr->next->next is not NULL.
Also, your if condition is also not correct. You should check for next!=NULL than data.
So update your ifs to
if(curr->next->!=NULL && curr->next->next->data!=NULL)
Also, try to use gdb or some other debugger to debug and see why your program is crashing and what are the problems.

Resources