I´m facing really weird issue with my headtail application. When I try to read from file data.txt using Powershell (command: Get-Content data.txt | .\Headtail.exe head 10) I always get proper and expected output. However if I change input from data.txt to fail.txt I won´t get any output from output function (called vypis()).
Does anyone have an idead what is going on here?
GOOD CASE: Output from command (this output is suppose to be same using fail.txt as an input (meaning that content of the given input should be printed)) Get-Content data.txt | .\Headtail.exe head 10 in PowerShell:
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
WRONG CASE: Output from command Get-Content fail.txt | .\Headtail.exe head 10 in PowerShell:
/*NOTHING */
Code for my headtail function is following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int const size = 15;
int last_changed = 0;
typedef struct {
char **field;
int *columns;
int rows;
} TMatrix;
void set_size(TMatrix* matrix) {
for (int i = 0; i < matrix->rows; i++) matrix->columns[i] = size;
}
TMatrix* allocate() {
TMatrix* matrix = malloc(sizeof(TMatrix));
if (!matrix) return NULL;
matrix->field = malloc(size * sizeof(char*));
if (!matrix->field) return NULL;
matrix->rows = size;
matrix->columns = malloc(size * sizeof(int));
if (!matrix->field) return NULL;
set_size(matrix);
for (int i = 0; i < matrix->rows; i++) {
matrix->field[i] = malloc(size * sizeof(char));
if (!matrix->field[i]) return NULL;
}
return matrix;
}
void release(TMatrix* matrix) {
for(int i = 0; i < matrix->rows; i++) free(matrix->field[i]);
free(matrix->field);
free(matrix->columns);
free(matrix);
}
bool add_rows(TMatrix* matrix) {
matrix->rows += 10;
char** rebuf = realloc(matrix->field, matrix->rows * sizeof(char*));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field = rebuf;
int* rebufl = realloc(matrix->columns, matrix->rows * sizeof(int));
if (!rebufl) {
free(rebufl);
return false;
}
matrix->columns = rebufl;
for (int i = 1; i <= 10; i++) {
char* rebuh = realloc(matrix->field[matrix->rows - i], size * sizeof(char));
if (!rebuh) {
free(rebuh);
return false;
}
matrix->field[matrix->rows - i] = rebuh;
matrix->columns[matrix->rows - i] = size;
}
return true;
}
bool add_column(TMatrix* matrix, int row) {
matrix->columns[row] += 15;
char* rebuf = realloc(matrix->field[row], matrix->columns[row] * sizeof(char));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field[row] = rebuf;
return true;
}
TMatrix* load(FILE* in) {
char c;
int actual_row = 0, actual_column = 0;
TMatrix* matrix;
if (!(matrix = allocate())) return NULL;
while ((fscanf(in, "%c", &c)) != EOF) {
matrix->field[actual_row][actual_column] = c;
if (c != '\n') {
actual_column += 1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
}
else if (c == '\n') {
actual_column +=1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
matrix->field[actual_row][actual_column] = '\0';
actual_column = 0;
actual_row += 1;
last_changed += 1;
if (((matrix->rows) - 1) == actual_row) {
if (!add_rows(matrix)) return NULL;
}
}
}
return matrix;
}
bool output(FILE* out, TMatrix *matrix, double num_of_output_lines, char method[]) {
if (!matrix) return false;
if (num_of_output_lines <= 0) return false;
if (matrix->rows <= 0) return false;
if (num_of_output_lines > last_changed) return false;
if (strcmp("head", method) == 0) {
for (int i = 0; i < num_of_output_lines; i++) {
for (int j = 0; j < matrix->columns[i]; j++) {
if (matrix->field[i][j] != '\0') fprintf(out, "%c", matrix->field[i][j]);
else break;
}
}
}
else if (strcmp("tail", method) == 0) {
for (int a = (last_changed-1); a >= (last_changed - num_of_output_lines); a--) {
for (int b = 0; b < matrix->columns[a]; b++) {
if (matrix->field[a][b] != '\0') fprintf(out, "%c", matrix->field[a][b]);
else break;
}
}
}
else return false;
return true;
}
void Help() {
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
fprintf(stdout, "* Help function - nothing important *\n");
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
}
int main(int argc, char *argv[])
{
if (argc < 3 || argc > 4) {
printf("!Valid count of arguments entered! \n");
return -1;
}
if (strcmp("-h", argv[1]) == 0) Help();
double num_of_output_lines = atoi(argv[argc - 1]);
TMatrix* matrix = load(stdin);
if (!matrix) {
printf("!Error while loading! \n");
return -1;
}
if (!output(stdout, matrix, num_of_output_lines, argv[argc - 2])) {
printf("!Error while printing! \n");
return -1;
}
release(matrix);
return 0;
}
And content of data.txt (works fine, just an example input):
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.
And finally content of fail.txt (didn´t get any output, the difference is just in length of some rows):
aaaaa.
bbbbbbb.
cccc.
ddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.
Related
I'm very novice at C but I'm trying to learn. I'm trying right now to make a program read from a csv file and take only it's integers from it, and write those out to a seperate .txt file. I'm not seeing why it will create a file, but why it won't write anything to it. Here's the code. in the methods 'getTokensFromLineforOutput' and 'writeOutput' is where I try to do my writing, everything else works fine, and if you were to take away those two methods and run it as just a program reading from a csv file it operates as intended. But writing is where I'm running into. IDK if i'm able to attach a document so for reference here's the csv file I made from notepad:
3,1, joe
45,0, sandy
5,1, mary
12,0, eugene
11,0, alex
#include <stdio.h>
#include <stdbool.h>
#define NAMESIZE 30
#define ARRAYSIZE 100
#define ROWLENGTH 300
#define TOKENLENGTH 10
typedef struct {
int nWeeks;
bool isCensored;
char identifier[NAMESIZE];
}SurvivalPatientData;
bool giveMeALine(FILE * source, char * dest)
{
bool status = false;
char * where = dest;
char ch;
int ch_ctr = 0;
while(((ch = getc(source)) != EOF) && (ch != '\n') && (ch != '\r'))
{
*where = ch;
where++;
ch_ctr++;
status = true;
}
for (int i=ch_ctr; i<ROWLENGTH && status ;i++)
{
*where= '\0'; /*null*/
where++;
}
printf("giveMeALine returning status = %d\n",status);
return status;
}
bool getTokensFromLineforOutput(char *theLine, SurvivalPatientData *sdp) {
bool status = false;
FILE * file = fopen("C:/Users/Default/Desktop/CCSU/CCSU SPRING 18/CS_3//output.txt", "w");
char * inTheLine = theLine;
char theToken[TOKENLENGTH];
char * inToken = theToken;
char ch = '\0';
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
int value = 0;
while((ch=*inTheLine)!=',')
{
value *= 10;
value += ch - '0';
inTheLine++;
}
sdp->nWeeks=value;
fprintf(file, "%d\n",sdp->nWeeks);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = theToken;
inTheLine++;
while((ch=*inTheLine)!=',')
{
*inToken = ch;
inToken++;
inTheLine++;
}
inToken--;
if (*inToken == '0')
{
sdp->isCensored=false;
}
else
{
sdp->isCensored= true;
}
fprintf(file, "%d\n",sdp->isCensored);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = sdp->identifier;
while((ch=*inTheLine)!=',' && ch!= EOF)
{
*inToken = ch;
inToken++;
inTheLine++;
}
status=true;
return status;
}
bool getTokensFromLine(char * theLine,
SurvivalPatientData * sdp);
bool getTokensFromLine(char *theLine, SurvivalPatientData *sdp) {
bool status = false;
char * inTheLine = theLine;
char theToken[TOKENLENGTH];
char * inToken = theToken;
char ch = '\0';
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
int value = 0;
while((ch=*inTheLine)!=',')
{
value *= 10;
value += ch - '0';
inTheLine++;
}
sdp->nWeeks=value;
printf("Weeks is %d\n",sdp->nWeeks);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = theToken;
inTheLine++;
while((ch=*inTheLine)!=',')
{
*inToken = ch;
inToken++;
inTheLine++;
}
inToken--;
if (*inToken == '0')
{
sdp->isCensored=false;
}
else
{
sdp->isCensored= true;
}
printf("isCensored is %d\n",sdp->isCensored);
inTheLine++;
for (int i = 0; i<TOKENLENGTH; i++)
{
theToken[i]='\0'; /*null char*/
}
inToken = sdp->identifier;
while((ch=*inTheLine)!=',' && ch!= EOF)
{
*inToken = ch;
inToken++;
inTheLine++;
}
printf("The identifier is %s\n",sdp->identifier);
status=true;
return status;
}
bool writeOutput(FILE * source, SurvivalPatientData * gotIt){
bool status = false;
bool write = false;
for (int j = 0; j<ARRAYSIZE; j++){
for (int i = 0; i<NAMESIZE; i++){
(gotIt[j].identifier)[i]='\x20';
}
gotIt[j].nWeeks = 0;
gotIt[j].isCensored = false;
}
int nrows = 0;
int row = 0;
char readALine[ROWLENGTH];
bool lines2Read = true;
bool gotTokens = false;
while (lines2Read){
bool gotALine = giveMeALine(source, readALine);
if(!gotALine){
lines2Read = false;
} else {
gotTokens = getTokensFromLineforOutput(readALine, &(gotIt[row]));
if(gotTokens){
status = true;
row++;
nrows++;
}
}
}
return status;
}
bool getInputFancy(FILE * source, SurvivalPatientData * gotIt){
bool status = false;
for (int j = 0; j<ARRAYSIZE; j++){
for (int i = 0; i<NAMESIZE; i++){
(gotIt[j].identifier)[i]='\x20';
}
gotIt[j].nWeeks = 0;
gotIt[j].isCensored = false;
}
int nrows = 0;
int row = 0;
char readALine[ROWLENGTH];
bool lines2Read = true;
bool gotTokens = false;
while (lines2Read){
bool gotALine = giveMeALine(source, readALine);
if(!gotALine){
lines2Read = false;
} else {
puts(readALine);
gotTokens = getTokensFromLine(readALine, &(gotIt[row]));
if(gotTokens){
printf("found %d row\n", row);
status = true;
row++;
nrows++;
}
}
}
printf("found %d rows\n", nrows);
return status;
}
int main() {
printf("Hello, World!\n");
bool readIt = false;
bool write = false;
SurvivalPatientData gotIt[ARRAYSIZE];
FILE * whereInputIs = fopen("C:/Users/Default/Desktop/CCSU/CCSU SPRING 18/CS_3//retake.csv", "r");
FILE * whereOutputIs = fopen("C:/Users/Default/Desktop/CCSU/CCSU SPRING 18/CS_3//output.txt", "w");
if (whereInputIs == NULL){
perror("can't open file source/doesn't exist");
}
puts("Found the file");
readIt = getInputFancy(whereInputIs, gotIt);
write = writeOutput(whereOutputIs, gotIt);
if (!readIt)
{
perror("could not read that file");
}
puts("!!!read the file!!!");
if (fclose ( whereInputIs) != 0) {
perror("trouble trying to close");
}
puts("!!!closed the file!!!");
return 0;
}
(If I could comment this I would)
Try putting parentheses around your de referencing * and variable..
(ch = (*inThLine))
I am reading from a txt file into an array of structures. Example txt:
-4.5 -1 0 0
4.0 1 0 0
8 0 1 2
12.1 0 -6 1
-3.2 2.5 -3.0 4
The 4 values of each line correspond to the 4 values in the structure. The file may contain up to 100 lines (MAX is defined as 100). With the following code I am trying to store each line into the respective index of the struct array and then print:
FILE *fileName = NULL;
typedef struct chargeData_struct {
double Q, x, y, z;
} ChargeData;
ChargeData values[MAX], *p = values;
fileName = fopen("charge2.txt", "r");
if (fileName == NULL)
{
printf("ERROR: Could not open file.");
}
int k = 0;
while (fscanf(fileName, "%lf %lf %lf %lf", &p[k].Q, &p[k].x, &p[k].y, &p[k].z) != EOF);
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
fclose(fileName);
However, only the last line of the txt file is printed. Is the same index of the struct array being overwritten each time?
You are using an extra semicolon which makes all the trouble, here:
while (fscanf(...) != EOF);
{
...
Remove it and you should be fine.
What happens with your code is that while(..); is equivalent to this:
while(...)
{
; // do nothing
}
thus does not enter the body (the one you think is the body) of your loop (since the actual body does nothing). However scanf() continues to parse the file, and then this section of your code executes:
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
independently, where the curly braces are treated like they wanted to state scope.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LINE_BUFFER_LEN (512)
#define RESERVE_NEWLINDE 0
#define AUTO_FILTER_NEWLINDE 1
typedef int (* LINE_READER)(char * pstrLine, int uiBufferLen, void * pvData);
typedef struct st_HW_SSP_CONFIG
{
const char * pstrConfigPath;
LINE_READER pfLineReader;
FILE * pstFile;
void * pvData;
int CurrentLine;
int Flag;
} CONFIG_ST;
int CloseConfig(CONFIG_ST * pstConfig)
{
if (!pstConfig)
{
// record error
return -1;
}
if (fclose(pstConfig->pstFile))
{
// record error
}
return 0;
}
int OpenConfigFile(const char * pstrFilePath, CONFIG_ST * pstConfig)
{
FILE * pstFile = NULL;
if ((!pstrFilePath) || (!pstConfig))
{
return -1;
}
pstFile = fopen(pstrFilePath, "r");
if (!pstFile)
{
return -1;
}
pstConfig->pstFile = pstFile;
pstConfig->pstrConfigPath = pstrFilePath;
pstConfig->Flag = RESERVE_NEWLINDE;
return 0;
}
int IsNullStr(const char *pcStr)
{
const char *pcTmp = pcStr;
while ('\0' != *pcTmp)
{
if (!isspace(*pcTmp))
{
return 0;
}
pcTmp++;
}
return 1;
}
int IsEffectiveLine(char acFileLineBuffer[LINE_BUFFER_LEN])
{
if (0 == strlen(&acFileLineBuffer[0]))
{
return 0;
}
if ('#' == acFileLineBuffer[0]) // strip as a comment line
{
return 0;
}
if (IsNullStr(&acFileLineBuffer[0]))
{
return 0;
}
return 1;
}
void FilterNewLine(char* pcLine, int MaxNumLen)
{
int uiLen = strlen(pcLine);
if (uiLen > 1)
{
if ('\n' == pcLine[uiLen - 1])
{
pcLine[uiLen - 1] = '\0';
if (uiLen > 2)
{
if ('\r' == pcLine[uiLen - 2])
{
pcLine[uiLen - 2] = '\0';
}
}
}
}
return;
}
int ReadConfigFile(CONFIG_ST * pstConfig)
{
char acFileLineBuffer[LINE_BUFFER_LEN] = {0};
char * pstrRead = NULL;
int Ret = 0;
if (!pstConfig)
{
return -1;
}
if ((!pstConfig->pstFile) || (!pstConfig->pfLineReader))
{
return -1;
}
rewind(pstConfig->pstFile);
pstConfig->CurrentLine = 0;
do
{
memset((void *)&acFileLineBuffer[0], 0, LINE_BUFFER_LEN);
pstrRead = fgets(&acFileLineBuffer[0], LINE_BUFFER_LEN - 1, pstConfig->pstFile);
if (pstrRead)
{
pstConfig->CurrentLine ++;
if (0 == IsEffectiveLine(acFileLineBuffer))
{
continue;
}
if (AUTO_FILTER_NEWLINDE == pstConfig->Flag)
{
FilterNewLine(acFileLineBuffer, LINE_BUFFER_LEN - 1);
}
if (pstConfig->pfLineReader)
{
Ret = pstConfig->pfLineReader(&acFileLineBuffer[0],
LINE_BUFFER_LEN,
pstConfig->pvData);
if (Ret)
{
break;
}
}
}
}
while (pstrRead);
return Ret;
}
int ReadConfigFileEx(const char * pFilePath,
LINE_READER pfReader,
void * pData, int Flag)
{
int Ret = 0;
CONFIG_ST stConfig = {0};
Ret = OpenConfigFile(pFilePath, &stConfig);
if (Ret)
{
return Ret;
}
stConfig.pfLineReader = pfReader;
stConfig.pvData = pData;
stConfig.Flag = Flag;
Ret = ReadConfigFile(&stConfig);
CloseConfig(&stConfig);
return Ret;
}
int StringSplit(char *pcStr, char cFlag,
char * pstArray[], int MaxNum,
int *pNum)
{
char * pcStrTemp = 0;
unsigned int uiIndex = 0;
pcStrTemp = pcStr;
while (pcStrTemp)
{
pstArray[uiIndex] = pcStrTemp;
pcStrTemp = strchr(pcStrTemp, cFlag);
if (pcStrTemp)
{
*pcStrTemp = '\0';
pcStrTemp ++;
uiIndex ++;
}
if (uiIndex >= MaxNum)
{
break;
}
}
if (0 != MaxNum)
{
*pNum = uiIndex >= MaxNum ? (MaxNum - 1) : uiIndex;
}
else
{
*pNum = 0;
}
return 0;
}
int MyLineReader(char * pstrLine, int uiBufferLen, void * pvData)
{
printf("Read line:[%s]\r\n", pstrLine);
char *pArray[8] = {0};
int Num = 0;
int index = 0;
StringSplit(pstrLine, ' ', pArray, 8, &Num);
for (index = 0; index <= Num; index ++)
{
printf("Get value :[%s]\r\n", pArray[index]);
}
return 0;
}
int main(int argc, char * argv[])
{
int ret = 0;
if (argc != 2)
{
printf("Please input file to read.\r\n");
return 0;
}
ret = ReadConfigFileEx(argv[1], MyLineReader, NULL, AUTO_FILTER_NEWLINDE);
if (ret)
{
printf("Open file error.\r\n");
}
return 0;
}
i'm an trying to write a program that will call a function win if there is n number of X's or O's in a row. I am have difficulty with the diagonal win that slopes upwards. can any offer any advice on what I should change? Thanks in advance. It calls an infinite loop instead of returning true.
bool left_diag_win(char **board, int num_rows, int num_cols) {
int i;
if (board[0][0] == '*') {
return false;
}
for (i = 1; i < num_rows; ++i) {
if (board[i][i] != board[0][0]) {
return false;
}
}
return true;
}
bool right_diag_win(char **board, int num_rows, int num_cols) {
int i;
if (board[0][num_cols - 1] == '*') {
return false;
}
for (i = 1; i < num_rows; ++i) {
if (board[i][num_cols - i - 1] != board[0][num_cols - 1]) {
return false;
}
}
return true;
}
You code seems correct, but you probably have a problem elsewhere. Here is an example where it behaves as expected:
#include <stdbool.h>
#include <stdio.h>
bool left_diag_win(char **board, int num_rows, int num_cols) {
if (board[0][0] == '*') {
return false;
}
for (int i = 1; i < num_rows; ++i) {
if (board[i][i] != board[0][0]) {
return false;
}
}
return true;
}
bool right_diag_win(char **board, int num_rows, int num_cols) {
if (board[0][num_cols - 1] == '*') {
return false;
}
for (int i = 1; i < num_rows; ++i) {
if (board[i][num_cols - i - 1] != board[0][num_cols - 1]) {
return false;
}
}
return true;
}
int main(void) {
char *matrix1[] = { "X****", "*X***", "**X**", "***X*", "****X" };
char *matrix2[] = { "****X", "***X*", "**X**", "*X***", "X****" };
printf("matrix:\n");
for (int i = 0; i < 5; i++) {
printf("%s\n", matrix1[i]);
}
printf("left-diagonal: %d\n", left_diag_win(matrix1, 5, 5));
printf("right-diagonal: %d\n\n", right_diag_win(matrix1, 5, 5));
printf("matrix:\n");
for (int i = 0; i < 5; i++) {
printf("%s\n", matrix2[i]);
}
printf("left-diagonal: %d\n", left_diag_win(matrix2, 5, 5));
printf("right-diagonal: %d\n\n", right_diag_win(matrix2, 5, 5));
return 0;
}
Output:
matrix:
X****
*X***
**X**
***X*
****X
left-diagonal: 1
right-diagonal: 0
matrix:
****X
***X*
**X**
*X***
X****
left-diagonal: 0
right-diagonal: 1
When I write:
printf("%f; ", massive[i]);
Where:
double** InputSystemOfLinearEquationsByFile(FILE* file) {
char* inputc = (char*)malloc(quiteenoughelements * sizeof(char));
int thenumberofvaribles = 0;
int thenumberofequations = 0;
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
thenumberofvaribles = atoi(inputc);
if (thenumberofvaribles <= 0) {
return NULL;
}
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
thenumberofequations = atoi(inputc);
if (thenumberofequations <= 0) {
return NULL;
}
double** answer = (double**)malloc(thenumberofequations*sizeof(double*));
for (int i = 0; i < thenumberofequations; i++) {
answer[i] = (double*)malloc((thenumberofvaribles + 1)*sizeof(double));
}
for (int i = 0; i < thenumberofequations; i++) {
for (int j = 0; j < thenumberofvaribles; j++) {
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
answer[i][j] = atof(inputc);
}
}
for (int i = 0; i < thenumberofequations; i++) {
if (fscanf(file, "%s", inputc) == EOF) {
return NULL;
}
answer[i][thenumberofvaribles] = atof(inputc);
}
free(inputc);
return answer;
}
void SwapStrokes(double** matrix, const unsigned int stroke1index, const unsigned int stroke2index) {
double* temp = matrix[stroke1index];
matrix[stroke1index] = matrix[stroke2index];
matrix[stroke2index] = temp;
temp = NULL;
}
unsigned char ZeroCheck(double** matrix, const unsigned int currentstroke, const unsigned int currentcolumn, const unsigned int numberofequations) {
int numberofnotzerocolumn = currentstroke;
while ((fabs(matrix[numberofnotzerocolumn][currentcolumn]) < accuracy) || (matrix[numberofnotzerocolumn][currentcolumn] != matrix[numberofnotzerocolumn][currentcolumn])) {
numberofnotzerocolumn++;
if (numberofnotzerocolumn == numberofequations) {
return 1;
}
}
if (numberofnotzerocolumn != currentstroke) {
SwapStrokes(matrix, currentstroke, numberofnotzerocolumn);
}
return 0;
}
void JordanException(double** matrix, const unsigned int currentstroke, const unsigned int currentcolumn, const unsigned int numberofvars, const unsigned int numberofequations) {
int optionalcolumn = 0;
int optionalstroke = 0;
for (optionalstroke = 0; optionalstroke < currentstroke; optionalstroke++) {
for (optionalcolumn = 0; optionalcolumn < currentcolumn; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
optionalcolumn++;
for (optionalcolumn; optionalcolumn <= numberofvars; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
}
for (optionalstroke = currentstroke + 1; optionalstroke < numberofequations; optionalstroke++) {
for (optionalcolumn = 0; optionalcolumn < currentcolumn; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
optionalcolumn++;
for (optionalcolumn; optionalcolumn <= numberofvars; optionalcolumn++) {
matrix[optionalstroke][optionalcolumn] -= matrix[optionalstroke][currentcolumn] * matrix[currentstroke][optionalcolumn] / matrix[currentstroke][currentcolumn];
}
}
for (optionalcolumn = 0; optionalcolumn < currentcolumn; optionalcolumn++) {
matrix[currentstroke][optionalcolumn] /= matrix[currentstroke][currentcolumn];
}
optionalcolumn++;
for (optionalcolumn; optionalcolumn <= numberofvars; optionalcolumn++) {
matrix[currentstroke][optionalcolumn] /= matrix[currentstroke][currentcolumn];
}
for (optionalstroke = 0; optionalstroke < numberofequations; optionalstroke++) {
matrix[optionalstroke][currentcolumn] = 0.;
}
matrix[currentstroke][currentcolumn] = 1.;
}
double* JordanMethod(double** matrix, const unsigned int numberofvars, const unsigned int numberofequations) {
if (numberofvars > numberofequations) {
return NULL;
}
else {
unsigned int currentcolumn = 0;
unsigned int currentstroke = 0;
while ((currentcolumn < numberofvars) && (currentstroke < numberofequations)) {
if (ZeroCheck(matrix, currentstroke, currentcolumn, numberofequations) == 1) {
return NULL;
}
JordanException(matrix, currentstroke, currentcolumn, numberofvars, numberofequations);
currentstroke++;
currentcolumn++;
}
double* answer = (double*)malloc(numberofvars * sizeof(double));
for (currentstroke = 0; currentstroke < numberofvars; currentstroke++) {
if ((fabs(matrix[currentstroke][numberofvars]) < accuracy) || (matrix[currentstroke][numberofvars] != matrix[currentstroke][numberofvars])){
matrix[currentstroke][numberofvars] = 0.;
}
answer[currentstroke] = matrix[currentstroke][numberofvars];
}
return answer;
}
}
void WriteMassive(double* massive, unsigned int numberofelements, FILE* file) {
if ((massive != NULL) && (file != NULL)){
for (unsigned int i = 0; i < numberofelements; i++) {
fprintf(file, "%f; ", massive[i]);
}
fprintf(file, "\n");
}
}
int main(int argc, char **argv)
{
double* matrixa = NULL;
double** matrix = NULL;
FILE* file;
FILE* output;
file = fopen("File.txt", "r");
matrix = InputSystemOfLinearEquationsByFile(file);
matrixa = JordanMethod(matrix, 4, 4);
WriteMassive(matrixa, 4, output);
fclose(file);
system("pause");
return 0;
}
My file has got:
4
4
2 -1 5 7
3 3,5 4 -5
-7 -3 7,2 5,3
4 3 2,1 -3,5
I face this bug, when i=0:
> Debug Assertion Failed! Program: ...ConsoleApplication1.exe File:
> minkernel\crts\ucrt\src\appcrt\convert\cfout.cpp Line: 126 Expression:
> ("unexpected input value; log10 failed, 0)
What should I do?
P.s. While debugging I move cursed to massive[i] and visual studio show that it has normal value (something like 6.29...).
I've tried my code on VS 2013 (instead of 2015) and... It worked! Idk how it works, maybe it just problem with my computer.
typedef struct {
int *info;
} row;
struct {
row* head;
int len;
int size;
} list;
int main{
list.len = 0;
list.size = 1;
list.head = malloc(list.size * sizeof(row));
//...... some other code that calls addRow (list.len) times
for (i = list.len - 1; i > 0; i--) {
free(list.head[i].info);/*****HERE**********/
}
free(list.head);
}
void addRow(int* data) {
int i;
if (list.len == list.size) {
row *temp = malloc(sizeof(row) * list.size * 2);
if (temp == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < list.len; i++) {
temp[i] = list.head[i];
}
free(list.head);
list.head = temp;
}
list.head[list.len].info = malloc(sizeof(int) * numCols);
for (i = 0; i < numCols; i++) {
list.head[list.len].info[i] = data[i];
}
list.len++;
}
This is the code that I used to addRow is were I malloc all the data. and I don't see why I'm getting a double free/ corruption error. At the area I marked HERE, I believe I am malloc-ing for all instances of info in the row struct, These line are the only ones doing malloc/free.
I just want to get into the habit free-ing properly when terminating the program.
FULL PROGRAM:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct {
int *info;
} row;
struct {
row* head;
int len;
int size;
} list;
static int sortCol, numCols;
int qSortCompare(const void*, const void*);
void printList();
int processInput();
void nullify(char*, int);
int main(int n, char **args) {
sortCol = 1;
numCols = 0;
if (n > 1 && args[1][0] == '-' && args[1][1] == 'c') {
sortCol = atoi(args[2]);
}
list.len = 0;
list.size = 1;
list.head = malloc(list.size * sizeof(row));
processInput();
if (sortCol < 1 || sortCol > numCols) {
fprintf(stderr, "Error (enter): (Line ##) Invalid column to sort.\n");
return 1;
}
printList();
qsort(list.head, list.len, sizeof(row), &qSortCompare);
printf("\n");
printList();
int i;
printf("add1:%p\nadd2:%p\n", list.head[0].info, list.head[1].info);
for (i = 0; i < list.len; i++) {
free(list.head[i].info);
}
free(list.head);
return 0;
}
void nullify(char* str, int n) {
int i;
for (i = 0; i < n; i++)
str[i] = '\0';
}
int parseInt(char *str, int index) {
int num = -1;
sscanf(str + index, "%d", &num);
return num;
}
void addRow(int* data) {
int i;
if (list.len == list.size) {
row *temp = malloc(sizeof(row) * list.size * 2);
if (temp == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < list.len; i++) {
temp[i] = list.head[i];
}
free(list.head);
list.head = temp;
}
list.head[list.len].info = malloc(sizeof(int) * numCols);
if (list.head[list.len].info == NULL) {
fprintf(stderr, "Error (enter): (Line ##) Insufficient memory.\n");
return;
}
for (i = 0; i < numCols; i++) {
list.head[list.len].info[i] = data[i];
}
list.len++;
}
int processInput() {
int i, maxChars = 200, totalN = 0;
int *nums, curNumIndex = 0, onNum, curNum;
numCols = maxChars / 2;
nums = (int*) (malloc(sizeof(int) * numCols));
char str[maxChars], ch;
for (i = 0; i < numCols; i++) {
nums[i] = -1;
}
while (!feof(stdin)) {
nullify(str, maxChars);
fgets(str, maxChars, stdin);
onNum = isdigit(str[0]);
curNumIndex = 0;
for (i = 0; i < maxChars; i++) {
ch = str[i];
if ((!isspace(ch)) && (!isdigit(ch)) && (ch != '\0')) {
fprintf(stderr, "Error 1: (Line ##) Invalid char in input.\n");
//return 0;
}
if (isspace(ch) && onNum) {
curNum = parseInt(str, curNumIndex);
curNumIndex = i;
nums[totalN % numCols] = curNum;
totalN++;
if (totalN % numCols == 0)
addRow(nums);
} else {
onNum = isdigit(str[i]);
}
if (ch == '\n' || ch == '\0')
break;
}
if (numCols > totalN) {
if (totalN > 0) {
numCols = totalN;
addRow(nums);
} else {
fprintf(stderr,
"Error (enter): (Line ##) Invalid first line of input.\n");
}
}
if (ch != '\n' && ch != '\0') {
fprintf(stderr,
"Error (enter): (Line ##) A row from input too long.\n");
//return 0;
}
}
return 1;
}
int qSortCompare(const void *c1, const void *c2) {
row *t1, *t2;
t1 = (row*)c1;
t2 = (row*)c2;
return t1->info[sortCol - 1] - t2->info[sortCol - 1];
}
void printList() {
int i, j;
for (i = 0; i < list.len; i++) {
for (j = 0; j < numCols; j++) {
printf("%10d ", list.head[i].info[j]);
}
printf("\n");
}
}
Program needs a EOF terminated input of integer numbers. Specifically with the same number of integers before the newline.
UPDATE: I used gdb to analysis the free part i it only fails on the second iteration, using for(i = 0; i < list.len; i++) and for(i = list.len - 1; i > 0 ; i--)
Another thing is that I don't see the update to list.size (it should be updated when resizing head)
"I just want to get into the habit free-ing properly when terminating the program."
The correct way to handle things like this is to free a non-NULL pointer and then set the pointer to NULL.
For example:
int* x = malloc (sizeof (int));
if (x != NULL) {
free (x);
x = NULL;
}
/* Misc. Code ... */
/* Now for whatever reason, you want to free x again */
/* This branch is never triggered, because you were smart enough to set x to NULL
* when you freed it the first time...
*/
if (x != NULL) {
free (x);
x = NULL;
}