Generated .txt file doesn't show up - c#

So, I'm tryng to generating a txt file with a matrix of 0 and 1, where all the borders are 0 and the body of the matrix is randomly filled with both values. It should be a bitMap where 0 is an obstacle and 1 is a possibile node for pathfinding algorythm. The Method should be called multiple times to generate and save in the folder as mush maps as the user want.
I made this class to generate the map:
public static class GenerateText
{
static string obstacle = "0";
static string node = "1";
public static void CreateMap(int x, int y, string name)
{
string path = "Assets/" + name + ".txt";
if(!File.Exists(name + ".txt"))
{
FileStream fs = File.Create(path);
StreamWriter writer = new StreamWriter(fs);
string[,] map = new string[x, y];
for (int i = 0; i < x; ++i)
{
for (int h = 0; h < y; ++h)
{
int randomValue = RandomGenerator.GetRandom(0, 10);
if (randomValue > 6 || i == 0 || h == 0 || i == x || h == y)
{
map[i, h] = obstacle;
}
else
{
map[i, h] = node;
}
}
}
fs.Close();
writer.WriteLine(map);
}
}
}
and the result should be something like this:
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
The called method works fine and reach the end, but if i check the solution the file that was supposed to be generated is missing.
I'm new to this kind of things so it's probably a dumb question, but can someone help me?

1- You are closing filestream before you write anything
2- You are trying to write a array . But you send just array object to the file you need the loop for that
public static class GenerateText
{
static string obstacle = "0";
static string node = "1";
public static void CreateMap(int x, int y, string name)
{
string path = Directory.GetCurrentDirectory() + "/" + name + ".txt";
if (!File.Exists(name + ".txt"))//if there is a empty file with this name
{ //function doesnt work make sure you
//delete any empty file
FileStream fs = File.Create(path);
StreamWriter writer = new StreamWriter(fs);
string[,] map = new string[x, y];
for (int i = 0; i < x; ++i)
{
for (int h = 0; h < y; ++h)
{
int randomValue = RandomGenerator.GetRandom(0, 10);
if (randomValue > 6 || i == 0 || h == 0 || i == x || h == y)
{
map[i, h] = obstacle;
}
else
{
map[i, h] = node;
}
}
}
for (int a = 0; a < x; a++)
{
for (int b = 0; b < y; b++)
{
writer.Write(map[a, b]);
}
writer.WriteLine();
}
writer.Close();
fs.Close();
}
}
}

You are closing your filestream before you write to your StreamWriter!
fs.Close();
writer.WriteLine(map);
It is better to have Using statements for such cases, then you minimise such problems. With or without brackets is your choice.
using (FileStream fs = File.Create(path))
using (StreamWriter writer = new StreamWriter(fs))
string[,] map = new string[x, y];
for (int i = 0; i < x; ++i)
{
for (int h = 0; h < y; ++h)
{
int randomValue = RandomGenerator.GetRandom(0, 10);
if (randomValue > 6 || i == 0 || h == 0 || i == x || h == y)
{
map[i, h] = obstacle;
}
else
{
map[i, h] = node;
}
}
}
writer.WriteLine(map);

Related

C# return string in Sine-Wave format

I'm trying to create a function which will return string in Triangle Sine-Wave format:
but currently, my format is only in Wave format:
Code below:
public static void printWave(string str)
{
int height = 3;
// Get length of the string
int len = str.Length;
// Create a 2d character array
char[,] matrixArray = new char[height, len];
char[] charArray = str.ToCharArray();
// for counting the
// rows of the ZigZag
int row = 0;
bool down = true;
for (int i = 0; i < len; i++)
{
// put characters
// in the matrix
matrixArray[row, i] = charArray[i];
// You have reached the bottom
if (row == height - 1)
down = false;
else if (row == 0)
down = true;
if (down)
row++;
else
row--;
}
// Print the Zig-Zag String
for (int i = 0; i < height; i++)
{
for (int j = 0; j < len; j++)
{
Console.Write(matrixArray[i, j] + " ");
}
Console.Write("\n");
}
}
Can you please help me modify my code to it will return triangle sin wave format?
We can use 3 separate StringBuilders to append to depending on our boolean top and a simple even value comparison. A quick TL;DR is that anything at an even index goes in the middle row, and then we flip between appending to the top or bottom row:
public static void printWave(string str)
{
//for use to determine top or bottom StringBuilder
bool top = true;
//will be used to generate each row of the output
StringBuilder topString = new StringBuilder();
StringBuilder middleString = new StringBuilder();
StringBuilder bottomString = new StringBuilder();
//iterate through paramter string
for (int i = 0; i < str.Length; i++)
{
//if char is at an even index, it goes in the middle StringBuilder, blank spaces in top and bottom builders
if (i%2 == 0)
{
topString.Append(" ");
middleString.Append(str[i]);
bottomString.Append(" ");
}
//if not even index, determine top or bottom row
else
{
//simply check our boolean and then flip it after use
if (top)
{
topString.Append(str[i]);
middleString.Append(" ");
bottomString.Append(" ");
top = false;
}
else
{
topString.Append(" ");
middleString.Append(" ");
bottomString.Append(str[i]);
top = true;
}
}
}
//write each row of strings on new lines
Console.WriteLine(topString.ToString());
Console.WriteLine(middleString.ToString());
Console.WriteLine(bottomString.ToString());
}
For a variable height:
public static void printWave(string str)
{
//height we want the wave to reach
int height = 5;
//determine "middle" row
int startingRow = height / 2;
int currentRow = startingRow; //this one is for modifying inside loop
bool up = true;
//2D array to hold the rows
char[,] arr = new char[height, str.Length];
for (int i = 0; i < str.Length; i++)
{
for (int j = 0; j < height; j++)
{
if (j == currentRow)
{
arr[j, i] = str[i];
}
else
arr[j, i] = ' ';
}
//could probably break this into more digestible pieces if time to think about it
if (up)
{
if (currentRow == 0)
{
up = false;
currentRow++;
}
else
{
currentRow--;
}
}
else
{
if (currentRow == height - 1)
{
up = true;
currentRow--;
}
else
{
currentRow++;
}
}
}
for (int k = 0; k < height; k++)
{
for (int l = 0; l < str.Length; l++)
{
Console.Write(arr[k, l]);
}
Console.WriteLine();
}
}
Examples of height = 5 and height = 6 output:
And finally, height = 7
This version works, but it's hard-coded to just the 3 rows like the question shows. If larger waves are needed, or especially if the size of the wave depends on the input string, then this may be hard to adjust to the requirements.
public static void PrintWave(string str)
{
printWithRowLogic(str, (i) => (i - 1) % 4 == 0);
Console.WriteLine();
printWithRowLogic(str, (i) => i % 2 == 0);
Console.WriteLine();
printWithRowLogic(str, (i) => (i - 3) % 4 == 0);
}
private static void printWithRowLogic(string str, Func<int, bool> checkLogic)
{
for (int i = 0; i < str.Length; i++)
Console.Write(checkLogic(i) ? str[i] : ' ');
}

Can someone say what i do wrong in C# task?

I need make symmetric letter “W” in string Array
get_w() Is method that should return string array that contains letter "W"
get_w(5) # should return:
public string[] GetW(int h)
{
if (h < 2) return new string[h];
int row = 0;
int stars_number = h * 4 - 3;
int times = 0;
StringBuilder[] c = new StringBuilder[h];
for(int a = 0; a < h; a++)
{
c[a] = new StringBuilder();
c[a].Length = stars_number;
}
for (int i = 0; i < stars_number; i++)
{
if (i == h - 1) times = 1;
if (i == stars_number-2 * h + 1) times = 2;
if (i == stars_number - h) times = 3;
c[row][i] = '*';
if (row < h - 1 && (times == 0 || times == 2))
{
row += 1;
}
else
{
row -= 1;
}
}
string []str = new string[h];
for(int i = 0; i < h; i ++)
{
str[i] = c[i].ToString();
}
return str;
}
if I compile it in a VS i get no errors.Here is an example of the result
This task is taken from the Codewars
but if I try to test on Codewars with the code I described above, I get this error
Edited:I changed returning array with "h" length to empty array and had got this
i found the task solution by replacing charters that equal '\0' with character ' '
here is working code
public string[] GetW(int h)
{
if (h < 2) return new string[]{};
int row = 0;
int stars_number = h * 4 - 3;
int times = 0;
StringBuilder[] c = new StringBuilder[h];
for(int a = 0; a < h; a++)
{
c[a] = new StringBuilder();
c[a].Length = stars_number;
}
for (int i = 0; i < stars_number; i++)
{
if (i == h - 1) times = 1;
if (i == stars_number-2 * h + 1) times = 2;
if (i == stars_number - h) times = 3;
c[row][i] = '*';
if (row < h - 1 && (times == 0 || times == 2))
{
row += 1;
}
else
{
row -= 1;
}
}
string []str = new string[h];
for(int i = 0; i < h; i ++)
{
c[i].Replace('\0', ' ');
str[i] = c[i].ToString();
}
return str;
}
And here is result of test

Trouble creating algorithm that modifies elements of a 2d array

I am having trouble editing the values of a 2d char array.
char[,] chrRaster = new char[4, 5];
After adding values to the array and printing it to the console, I get:
// Input example:
*****
**.**
*****
****.
I am trying to make an algorithm that replaces every '*' that is beside, under or above a '.' by a '.' and then printing this to the console.
// Output after algorithm example:
**.**
*...*
**.*.
***..
I have tried converting the 2d char array to a 2d string array and then using IndexOf('*') to replace every '*' that is beside, under or above a '.', and I also tried calculating this using a number of if and for loops without any luck.
static void Main(string[] args)
{
// Variablen
int intTestgeval = 0; // Number of times you want program to repeat
int intN = 0; // Number of rows
int intM = 0; // Number of coloms
char chrGrond; // Used to store '*' or '.'
char[,] chrRaster; // 2d char array used to store all values
// Code
try
{
intTestgeval = Int32.Parse(Console.ReadLine()); // Number of times program will repeat
if(intTestgeval > 150) // Program can not repeat more then 150 times
{
throw new Exception();
}
}
catch (Exception)
{
Environment.Exit(0);
}
intN = Controle(intN); // Number of rows ophalen
intM = Controle(intM); // Number of Coloms ophalen
chrRaster = new char[intN, intM]; // Initializing array with user input
for (int intR = 0; intR < intTestgeval; intR++) // Print 2d array to console
{
for(int intY = 0; intY < intN; intY++)
{
for(int intZ = 0; intZ < intM; intZ++)
{
chrGrond = Convert.ToChar(Console.ReadKey().KeyChar);
chrRaster[intY, intZ] = chrGrond;
}
Console.WriteLine();
}
instorten[intR] = Instorten(chrRaster, intN, intM); // Ignore this part, that's another part of my assignment not related to my question.
}
}
static int Controle( int intX )
{
try
{
intX = Int32.Parse(Console.ReadLine());
if (intX > 150 || intX < 1) // Length of row and colom can not exceed 20 and can not go lower then 1
{
throw new Exception();
}
return intX;
}
catch // Program will off if value does not meet requirements
{
Environment.Exit(0);
return intX;
}
}
// It is this part of the program I need help with. This is what I tried but can't get any further
static int Instorten(char[,] chrRaster, int intN, int intM)
{
for (int intY = 0; intY < intN; intY++)
{
for (int intZ = 0; intZ < intM; intZ++)
{
if(chrRaster[intY, intZ] == '.' && chrRaster[intY, intZ + 1] == '*' || chrRaster[intY, intZ] == '*' && chrRaster[intY, intZ + 1] == '.')
{
}
}
Console.WriteLine();
}
int intm = 0;
return intm;
}
}
One way to do this would be to make a copy of the array and then iterate over it, examining each item. If the item is a '.', then update the neighbors of this item in the original array.
To determine the neighbors, we simply add one to the row to get the neighbor below, subtract one from the row to get the neighbor above, and similarly we can get the right and left neighbors by adding/subtracting from the column value. Of course we need to ensure that we're inside the bounds of the array before doing anything.
We could write a method with this logic that might look like:
private static void ExposeDotNeighbors(char[,] input)
{
if (input == null) return;
// Make a copy of the input array that we can iterate over
// so that we don't analyze items that we've already changed
var copy = (char[,]) input.Clone();
for (var row = 0; row <= copy.GetUpperBound(0); row++)
{
for (var col = 0; col <= copy.GetUpperBound(1); col++)
{
if (copy[row, col] == '.')
{
// Update neighbors in original array
// Above = [row - 1, col], Below = [row + 1, col],
// Left = [row, col - 1], Right = [row, col + 1]
// Before updating, make sure we're inside the array bounds
if (row > 0) input[row - 1, col] = '.';
if (row < input.GetUpperBound(0)) input[row + 1, col] = '.';
if (col > 0) input[row, col - 1] = '.';
if (col < input.GetUpperBound(1)) input[row, col + 1] = '.';
}
}
}
}
We can also write some helper methods that will give us the initial array and to print an array to the console (also one that will write a header to the console):
private static char[,] GetInitialArray()
{
var initialArray = new char[4, 5];
for (var row = 0; row <= initialArray.GetUpperBound(0); row++)
{
for (var col = 0; col <= initialArray.GetUpperBound(1); col++)
{
if ((row == 1 && col == 2) || (row == 3 && col == 4))
{
initialArray[row, col] = '.';
}
else
{
initialArray[row, col] = '*';
}
}
}
return initialArray;
}
private static void PrintArrayToConsole(char[,] input)
{
if (input == null) return;
for (var row = 0; row <= input.GetUpperBound(0); row++)
{
for (var col = 0; col <= input.GetUpperBound(1); col++)
{
Console.Write(input[row, col]);
}
Console.WriteLine();
}
}
private static void WriteHeader(string headerText)
{
if (string.IsNullOrEmpty(headerText))
{
Console.Write(new string('═', Console.WindowWidth));
return;
}
Console.WriteLine('╔' + new string('═', headerText.Length + 2) + '╗');
Console.WriteLine($"║ {headerText} ║");
Console.WriteLine('╚' + new string('═', headerText.Length + 2) + '╝');
}
With these helper methods, we can then write code like:
private static void Main()
{
var chrRaster = GetInitialArray();
WriteHeader("Before");
PrintArrayToConsole(chrRaster);
ExposeDotNeighbors(chrRaster);
WriteHeader("After");
PrintArrayToConsole(chrRaster);
GetKeyFromUser("\nDone! Press any key to exit...");
}
And out output would look like:
I noticed that you also appear to be getting the values from the user, and using try/catch blocks to validate the input. A better approach might be to write a helper method that takes in a string that represents the "prompt" to the user, and a validation method that can be used to validate the input. With this, we can keep asking the user for input until they enter something valid.
Below are methods that get an integer and a character from the user, and allow the caller to pass in a function that can be used for validation. These methods will not return until the user enters valid input:
private static char GetCharFromUser(string prompt, Func<char, bool> validator = null)
{
char result;
var cursorTop = Console.CursorTop;
do
{
ClearSpecificLineAndWrite(cursorTop, prompt);
result = Console.ReadKey().KeyChar;
} while (!(validator?.Invoke(result) ?? true));
Console.WriteLine();
return result;
}
private static int GetIntFromUser(string prompt, Func<int, bool> validator = null)
{
int result;
var cursorTop = Console.CursorTop;
do
{
ClearSpecificLineAndWrite(cursorTop, prompt);
} while (!int.TryParse(Console.ReadLine(), out result) ||
!(validator?.Invoke(result) ?? true));
return result;
}
private static void ClearSpecificLineAndWrite(int cursorTop, string message)
{
Console.SetCursorPosition(0, cursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, cursorTop);
Console.Write(message);
}
We can then re-write our GetInitialArray method to use these methods to get the dimensions and values from the user:
private static char[,] GetInitialArray()
{
const int maxCols = 20;
const int maxRows = 20;
var numCols = GetIntFromUser(
$"How many columns do you want (1 - {maxCols}): ",
i => i > 0 && i <= maxCols);
var numRows = GetIntFromUser(
$"How many rows do you want (1 - {maxRows}): ",
i => i > 0 && i <= maxRows);
var initialArray = new char[numRows, numCols];
for (var row = 0; row <= initialArray.GetUpperBound(0); row++)
{
for (var col = 0; col <= initialArray.GetUpperBound(1); col++)
{
initialArray[row, col] = GetCharFromUser(
$"Enter value for [{row}, {col}] ('.' or '*'): ",
c => c == '.' || c == '*');
}
}
return initialArray;
}
And now our output might look like this:
If you try it, notice that you cannot enter an illegal value. The program just waits for you to read the instructions and enter a valid number or character. :)
Here is the algorithm that does what you want. I have tried to explain my code in the comments. The output will match what you're looking for.
static void Main(string[] args)
{
char STAR = '*';
char DOT = '.';
var input = new char[,]
{
{ STAR,STAR,STAR,STAR,STAR},
{ STAR,STAR,DOT,STAR,STAR},
{ STAR,STAR,STAR,STAR,STAR},
{ STAR,STAR,STAR,STAR,DOT}
};
var output = new char[4, 5];
// Copy each from input to output, checking if it touches a '.'
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 5; y ++)
{
if (input[x, y] == STAR)
{
var isDot = false;
// Check left
if (x > 0)
isDot = input[x - 1, y] == DOT;
// Check right
if (x < 3)
isDot = isDot || (input[x + 1, y] == DOT);
// Check above
if (y > 0)
isDot = isDot || (input[x, y - 1] == DOT);
// Check below
if (y < 4)
isDot = isDot || (input[x, y + 1]) == DOT;
output[x, y] = isDot ? DOT : STAR;
}
else
{
output[x, y] = input[x, y];
}
}
}
// Print output
for (int x = 0; x < 4; x ++)
{
for (int y = 0; y < 5; y ++)
{
Console.Write(output[x, y]);
}
Console.WriteLine();
}
Console.Read();
}
You can go like this :
using System;
public class chars
{
public static void Main(string[] args)
{
char[,] charArray = new char[,] {{'*','*','*','*','*'},
{'*','*','.','*','*'},
{'*','*','*','*','*'},
{'*','*','*','*','.'}};
int[,] holdIndex = new int[4, 5];
for(int i = 0; i<4; i++) // get allindexes containing '.'
{
for(int j = 0; j<5; j++)
{
if(charArray[i,j] == '.')
holdIndex[i,j] = 1;
else
holdIndex[i,j] = 0;
}
}
for(int i = 0; i<4; i++)
{
for(int j = 0; j<5; j++)
{
if(holdIndex[i,j] == 1)
{
if(i!=0)
charArray[i-1,j] = '.'; //up
if(j!=0)
charArray[i,j-1] = '.'; // left
if(j!=4)
charArray[i,j+1] = '.'; //right
if(i!=3)
charArray[i+1,j] = '.'; //down
}
}
}
for(int i = 0; i<4; i++)
{
for(int j = 0; j<5; j++)
{
Console.Write(charArray[i,j]);
}
Console.WriteLine();
}
Console.Read();
}
}

File Byte Array Encryption corrupt the file except Text Document

I made a simple file binary encrypt/decrypt and it works perfectly for any text document.
But when I encrypt and decrypt image / word document file, the file corrupt.
I don't understand why this happen.
This is my code to get the file byte array.
byte[] b = null;
using (System.IO.FileStream fr = new System.IO.FileStream(this.txtFile.Text, System.IO.FileMode.Open))
{
using (System.IO.BinaryReader br = new System.IO.BinaryReader(fr))
{
b = br.ReadBytes((int)fr.Length);
}
}
And this is how I write all the bytes back.
System.IO.File.WriteAllBytes(filepath, b);
Can someone explain to me why?
Edit : This is my Encrypt/Decrypt code.
Sorry if its messy, I'm new to cryptograph.
for (int i = 0; i < b.Length; i++)
{
if (keyIndex >= key.Length)
{
keyIndex = 0;
}
string fileBIN = Convert.ToString(b[i], 2);
string keyBIN = Convert.ToString(Convert.ToInt32(Convert.ToChar(key[keyIndex])), 2);
string newBIN = string.Empty;
keyIndex += 1;
if (fileBIN.Length > keyBIN.Length)
{
for (int x = 0; x < Math.Abs(fileBIN.Length - keyBIN.Length); x++) { keyBIN = "0" + keyBIN; x -= 1; }
}
else
{
for (int x = 0; x < Math.Abs(fileBIN.Length - keyBIN.Length); x++) { fileBIN = "0" + fileBIN; x -= 1; }
}
if (fileBIN == keyBIN)
{
newBIN = fileBIN;
}
else
{
for (int x = 0; x < fileBIN.Length; x++)
{
if (fileBIN.Substring(x, 1).ToString() == keyBIN.Substring(x, 1).ToString()) { newBIN += "0"; }
else { newBIN += "1"; }
}
}
b[i] = Convert.ToByte(newBIN, 2);
}

Declaring of arrays in C#

I have written the following code in an effort to try and compute the values down there below, but all my arrays do not work; especially the ones in the for loops. Can someone help teach me how to declare an array inside a loop? They keep showing errors like "Did you miss declaring a new object?"
Thanks
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
public class seasonal
{
public float mTotal;
public float movingAverage;
public int y;
public char quarter;
public char ssq;
public int rank;
public float forecast;
public float centralMovingAverage;
public float cmTotal;
public float sSeasonal;
}
public static int i;
public static int j;
public static int k = 0;
public static int n;
static void Main(string[] args)
{
int x; int r; int m; int c; int u = 0;
seasonal temp = new seasonal();
int n1; int n2; int n3; int n4; int sumr1 = 0; int sumr2 = 0; int sumr3 = 0; int sumr4 = 0;
float h; float ss; float sum; float sums1 = 0; float sums2 = 0; float sums3 = 0; float sums4 = 0; float tsums;
Console.WriteLine("Enter the no. of observations");
string nObservations = Console.ReadLine();
n = Convert.ToInt32(nObservations);
seasonal[] seasonal = new seasonal[n];
seasonal[] s = new seasonal[n];
for (i = 0; i < n; i++)
{
Console.Write("{0:D}:", (i+1) );
string value = Console.ReadLine();
int observation = Convert.ToInt32(value);
seasonal thisSeasonal = new seasonal();
thisSeasonal.y = observation;
seasonal[i] = thisSeasonal;
if (i>=0 && i<3)
{
seasonal[i].quarter = '1';
}
if (i>=3 && i<6)
{
seasonal[i].quarter = '2';
}
if (i>=6 && i<9)
{
seasonal[i].quarter = '3';
}
if (i>=9 && i<12)
{
seasonal[i].quarter = '4';
}
if (i>12)
{
r = i % 12;
if (r>=0 && r<3)
{
seasonal[i].quarter = '1';
}
if (r>=3 && r<6)
{
seasonal[i].quarter = '2';
}
if (r>=6 && r<9)
{
seasonal[i].quarter = '3';
}
if (r>=9 && r<12)
{
seasonal[i].quarter = '4';
}
}
for (i = k; i < n-3; i++)
{
sum = 0;
for (j = u+k; j < 4+k; j++)
{
sum += seasonal[j].y;
seasonal[i].mTotal = sum;
seasonal[i].movingAverage = seasonal[i].mTotal / 4;
Console.Write("{0:f}", seasonal[i].movingAverage);
k++;
}
}
for ( i = 0; i < (n-4); i++)
{
ss = 0;
for (j = 0; j < (2+i); j++)
{
ss += seasonal[j].movingAverage;
}
seasonal[i].cmTotal = ss;
seasonal[i].centralMovingAverage = seasonal[i].cmTotal / 2;
seasonal[i].sSeasonal = (seasonal[i+2].y)/(seasonal[i].centralMovingAverage);
if (i == 0 || i % 4 == 0)
{
seasonal[i].ssq = '3';
}
if (i == 1 || i % 4 == 1)
{
seasonal[i].ssq = '4';
}
if (i == 2 || i % 4 == 2)
{
seasonal[i].ssq = '1';
}
if (i == 3 || i % 4 == 3)
{
seasonal[i].ssq = '2';
}
Console.Write("\n{0:f}", seasonal[i].centralMovingAverage);
Console.Write("\n {0:f}", seasonal[i].sSeasonal);
}
}
for (m= 0; m < n; m++)
{
s[m] = seasonal[m];
}
for ( i = 0; i < (n-5); i++)
{
for ( j = 0; j < (n-4); j++)
{
if (s[i].sSeasonal > s[j].sSeasonal)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
for ( k = 0; k < (n-4); k++)
{
s[k].rank = k + 1;
Console.Write("\n\t {0:D}", s[k].rank);
}
for ( i = 0; i < (n-4); i++)
{
if (s[i].ssq == '1')
{
sumr1 += s[i].rank;
sums1 += s[i].sSeasonal;
//n1 ++;
}
if (s[i].ssq == '2')
{
sumr2 += s[i].rank;
sums2 += s[i].sSeasonal;
//n2++;
}
if (s[i].ssq == '3')
{
sumr3 += s[i].rank;
sums3 += s[i].sSeasonal;
//n3++;
}
if (s[i].ssq == '4')
{
sumr4 += s[i].rank;
sums4 += s[i].sSeasonal;
//n4++;
}
}
tsums = ((sums1/4)+(sums2/4)+(sums3/4)+(sums4/4));
Console.Write("\n\n\n{0:f}",tsums);
Console.Write("\n\n\n\n\n{0:D}",sumr1);
Console.Write("\n\n\n\n{0:D}",sumr2);
Console.Write("\n\n\n\n{0:D}",sumr3);
Console.Write("\n\n\n\n\n{0:D}",sumr4);
Console.Write("\n{0:f}",sums1/4);
Console.Write("\n\n{0:f}",sums2/4);
Console.Write("\n\n{0:f}",sums3/4);
Console.Write("\n\n{0:f}",sums4/4);
Console.Write("\n{0:f}",((sums1/4)/tsums)*4);
Console.Write("\n\n{0:f}",((sums2/4)/tsums)*4);
Console.Write("\n\n{0:f}",((sums3/4)/tsums)*4);
Console.Write("\n\n{0:f}",((sums4/4)/tsums)*4);
}
}
}
You need to initialise the objects in your arrays:
Seasonal[] seasonal = new Seasonal[n];
for (int l = 0; l < seasonal.Length; l++)
{
seasonal[l] = new Seasonal();
}
Seasonal[] s = new Seasonal[n];
for (int l = 0; l < s.Length; l++)
{
s[l] = new Seasonal();
}
This only solves the initialisation problem, though. You may want to look at naming conventions for readability, and then the index off by 1 you'll experience at roughly line 105.
instead of working with
seasonal[] seasonal = new seasonal[n];
seasonal[] s = new seasonal[n];
do work with
seasonal[] s1 = new seasonal[n];
seasonal[] s2 = new seasonal[n];
But when I see code like, this, where you just copy your array:
for (m= 0; m < n; m++)
{
s[m] = seasonal[m];
}
why would you do that? copy the entire array instead of every single entry..
why do you not use any c# constructs?
The problem is this line:
sum += seasonal[j].y;
But there isn't a simple fix. You are creating each object individually through the loop instead of before you enter the loop so each iteration is looking at null objects. Also, the loop this line is in reads past the end of the array. The code is a bit complex to easily see what you're trying to do and how to fix it.
Just an example for to simplify some of your code:
you wrote the following:
if (i>=0 && i<3)
{
seasonal[i].quarter = '1';
}
if (i>=3 && i<6)
{
seasonal[i].quarter = '2';
}
if (i>=6 && i<9)
{
seasonal[i].quarter = '3';
}
if (i>=9 && i<12)
{
seasonal[i].quarter = '4';
}
if (i>12)
{
r = i % 12;
if (r>=0 && r<3)
{
seasonal[i].quarter = '1';
}
if (r>=3 && r<6)
{
seasonal[i].quarter = '2';
}
if (r>=6 && r<9)
{
seasonal[i].quarter = '3';
}
if (r>=9 && r<12)
{
seasonal[i].quarter = '4';
}
}
you could write that instead:
if(i >= 0)
seasonal[i].quarter = (((i % 12)/3) + 1).ToString();
I don' think this code
seasonal[] seasonal = new seasonal[n];
seasonal[] s = new seasonal[n];
is correct. Try
seasonal[] seas = (seasonal[])Array.CreateInstance(typeof(seasonal), n);

Categories

Resources