Home > Net >  C Comparing Value of Pointer Char Array to A Char Value
C Comparing Value of Pointer Char Array to A Char Value

Time:05-03

Each day of the month is designated as either rainy (‘R’), cloudy (‘C’), or sunny (‘S’). The program should store this information in a 3 × 30 2D array of characters, where the row indicates the month (0 = June, 1 = July, 2 = August) and the column indicates the day of the month. Note that data are not being collected for the 31st day of any month. The program should begin by reading the weather data into the 2D array from a file named RainOrShine.txt. Then it should create a report that displays, for each month and for the whole three-month period, how many days were rainy, how many were cloudy, and how many were sunny. It should also report which of the three months had the largest number of rainy days.

I can only use pointers in this program, and I couldn't compare the value of the char pointer array to a char. I've tried

void print(const char* ptr, int* p, const int days, const int months)
{
    int rainy, sunny, cloudy;
    int rainySum = 0, sunnySum = 0, cloudySum = 0;

    cout << setw(28) << "Summer Weather Report" << endl;
    cout << endl;

    cout << setw(10) << left << "Month" << "Rainy " << setw(10) << right << "Cloudy" << setw(10) << "Sunny" << endl;

    for(int i = 0; i <= 8; i  )
    {
        cout << "____";
    }

    cout << endl;

    for(int i = 0; i < days*months; i  )
    {
        rainy = 0;
        sunny = 0;
        cloudy = 0;

        for(int j = 0; j < days; j  )
        {
            if(*(ptr   (i*days)   j) == 'R')
            {
                rainy  ;
                (*(p   (i*months)   0)) = rainy;
            }
            else if(*(ptr   (i*days)   j) == 'C')
            {
                cloudy  ;
                (*(p   (i*months)   0)) = cloudy;
            }
            else if(*(ptr   (i*days)   j) == 'S')
            {
                sunny  ;
                (*(p   (i*months)   0)) = sunny;
            }
        }
    }
    for(int i = 0; i < days; i  )
    {
        if(i == 0)
        {
            cout << setw(10) << left << "June";
        }
        else if(i == 1)
        {
            cout << setw(10) << left << "July";
        }
        else if (i == 2)
        {
            cout << setw(10) << left << "August";
        }
        
        for(int j = 0; j < days; j  )
        {
            cout << setw(10) << right << *(p   ((i*3)   j));
        }
        cout << endl;
    }

    for(int i = 0; i <= 8; i  )
    {
        cout << "____";
    }

    cout << endl;

    for(int i = 0; i < months; i  )
    {
        rainySum  = *(p   (i*months)   0);
        cloudySum  = *(p   (i*months)   1);
        sunnySum  = *(p   (i*months)   2);
    }

    cout << setw(10) << left << "Totals" << rainySum << setw(6) << sunnySum << setw(6) << cloudySum << endl;
}

This won't print out what I wanted.

This is my main

    char weather[NUM_OF_MONTHS][NUM_OF_DAYS];
    int sum[3][30];

    char* ptr = &weather[0][0];
    int* p = &sum[0][0];
   
    input(ptr);
    print(ptr, p, NUM_OF_DAYS, NUM_OF_MONTHS);

This is the assignment prompt and this is what the output is supposed to be.

Edit: This is what the source code contains

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
// add prototypes for your functions
    const int NUM_OF_MONTHS = 3;
const int NUM_OF_DAYS = 30;
int main()
{
// this 2D array stores the 90 values from the RainOrShine.txt text file
char weather[NUM_OF_MONTHS][NUM_OF_DAYS];
char* ptr = &weather[0][0]; // this pointer points to the beginning of the 2D
array
                            // Remember -- no using the brackets/subscripts 
([]'s)! 
                            // Everything should be handled with pointer 
offset notation
                            // and/or pointer arithmetic
   
//implement the rest of main
// system("PAUSE");
return 0;
}
// implement your functions

CodePudding user response:

It is illegal to traverse an array of arrays (a "2D array") as if it were a contiguous "1D" array. The C standard says:

if P points to an array element i of an array object x with n elements ([dcl.array]), the expressions P J and J P (where J has the value j) point to the (possibly-hypothetical) array element i j of x if 0≤i j≤n [...]
Otherwise, the behavior is undefined

In your example, ptr points to the first element of the char array weather[0]. Only elements of that array from weather[0][0] to (the hypothetical) weather[0][NUM_OF_DAYS] can be accessed via p. Other elements of weather, namely weather[1] through (the hypothetical) weather[NUM_OF_MONTHS], are not legal to access, doing so is undefined behaviour. Similarly, p points to the first element of sum[0], so sum[1] and the rest of them are all out of bounds.

If the assignment requires you to access your 2D arrays this way, then it is not doable in standard C . You may or may not get lucky violating the C standard and doing the illegal thing anyway. But you probably cannot do it by mixing all of your sizes up. You need a 3x30 source table (months x day-in-month) and a 3x3 summary table (months x day-types, which is one of rainy, sunny and cloudy). Why is sum a 3x30 array? Speaking of sum, what is it doing in main? It is not used there. It should be a local variable in a function that actually uses it.

It is however possible to declare weather as a 1D array:

weather[NUM_OF_MONTHS * NUM_OF_DAYS];

Same about sum. This will make pointer arithmetic on their respective pointers legal from the point of view of the C language (but you still need to fix the calculations and loop bounds which are all completely wrong).

I recommend to write it using normal 2D array notation first, debug it, make sure it is fully working, then translate it by hand to the 1D pointer notation, not all at once but statement by statement, checking that it works after every single change, until no array notation remains. Note that you will need to translate only the indexing expressions, not loop bounds. If you encounter problems during the first stage, ask a question about these problems first without mixing the pointer arithmetic notation in. You need to solve one problem at a time rather than all at once.

CodePudding user response:

I tried changing the code to be like this

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

// add prototypes for your functions
void input(char *);
void printDetermine(char*);

    const int NUM_OF_MONTHS = 3;
    const int NUM_OF_DAYS = 30;

int main()
{

    // this 2D array stores the 90 values from the RainOrShine.txt text file
    char weather[NUM_OF_MONTHS][NUM_OF_DAYS];
    int sum[3][30];

    char* ptr = &weather[0][0]; // this pointer points to the beginning of the 2D array
                                // Remember -- no using the brackets/subscripts ([]'s)! 
                                // Everything should be handled with pointer offset notation
                                // and/or pointer arithmetic
   
    //implement the rest of main
    input(ptr);
    cout << ptr;
    printDetermine(ptr);

//  system("PAUSE");
    return 0;
}

// implement your functions
void input(char* ptr)
{
    ifstream inputFile;
    inputFile.open("RainOrShine.txt");
    char x;

    if(!inputFile.is_open())
        cout << "File cannot be opened!" << endl;
    
    while(inputFile >> x)
    {
        *ptr = x;
        *ptr  ;
    }

    inputFile.close();
}

void printDetermine(char* ptr)
{
    cout << setw(28) << "Summer Weather Report" << endl;
    cout << endl;

    cout << setw(10) << left << "Month" << "Rainy " << setw(10) << right << "Cloudy" << setw(10) << "Sunny" << endl;

    int rainy, sunny, cloudy;
    int rainySum = 0, sunnySum = 0, cloudySum = 0;
    int mostRainyMonth = 0;

    for(int i = 0; i <= 8; i  )
    {
        cout << "____";
    }

    cout << endl;

    for(int i = 0; i < NUM_OF_MONTHS; i  )
    {
        rainy = 0;
        sunny = 0;
        cloudy = 0;


        for(int j = 0; j < NUM_OF_DAYS; j  )
        {
            if(*ptr == 'R')
            {
                rainy  ;
                rainySum  ;
            }
            else if(*ptr == 'C')
            {
                cloudy  ;
                cloudySum  ;
            }
            else if(*ptr == 'S')
            {
                sunny  ;
                sunnySum  ;
            }
            ptr  ;
        }

        if(rainy > 0)
        {
            mostRainyMonth = i;
        }

        if(i == 0)
        {
            cout << setw(10) << left << "June";
        }
        else if (i == 1)
        {
            cout << setw(10) << left << "July";
        }
        else if (i == 2)
        {
            cout << setw(10) << left << "August";
        }
        
        cout << setw(5) << right << rainy << cloudy << sunny << endl;;
    }



    for(int i = 0; i <= 8; i  )
    {
        cout << "____";
    }

    cout << endl;


    cout << setw(10) << left << "Totals" << rainySum << setw(6) << sunnySum << setw(6) << cloudySum << endl;
}

I altered this part

if(*(ptr   (i*days)   j) == 'R')
            {
                rainy  ;
                (*(p   (i*months)   0)) = rainy;
            }
            else if(*(ptr   (i*days)   j) == 'C')
            {
                cloudy  ;
                (*(p   (i*months)   0)) = cloudy;
            }
            else if(*(ptr   (i*days)   j) == 'S')
            {
                sunny  ;
                (*(p   (i*months)   0)) = sunny;
            }

I also tried to print out the pointer array, and it successfully imported the file

cout << ptr;

Currently this is what my code prints out

SRRSRRRRSSSSCSCCRCRRSCRCCSCSSRSCCCSCRRRSRCSRSCCRCCCCCRRRCRRCCRSSCRRCRRSCRRSSRRRRRCSCCRSRRR       Summer Weather Report

Month     Rainy     Cloudy     Sunny
____________________________________
June         11811
July         11145
August       1677
____________________________________
Totals    3823    29  

I'm almost completely out of idea on what to do next.

  • Related