How is a JPEG file formated? - jpeg

I'm trying to write Bytes into a JPEG file, but I don't know the file's format and so the Bytes aren't in the right place of the image after writing into the file.
Does somebody know?

There are several markers that must appear in a JPEG file stream. I believe you can easily find the detailed description of the tags listed below on Internet.
SOI(0xFFD8) Start of Image
APP0(0xFFE0) Application
[APPn(0xFFEn)] (alternative)
DQT(0xFFDB) Define Quantization Table
SOF0(0xFFC0) Start of Frame
DHT(0xFFC4) Difine Huffman Table
SOS(0xFFDA) Start of Scan
DRI(0xFFDD) Define Restart Interval,(alternative)
...Image Stream
EOI(0xFFD9) End of Image
Those markers are followed by lengths in BIG ENDIAN format. You can decode Image Stream that exactly follows DRI using the huffman trees you decoded by DQT. For easier illustration, here are some functions I have written on my own in Java that decodes a header of JPEG, but without doubt there are many better JPEG Java projects on Github that you can refer to.
public int[][] cutX(byte[] x){
int s = x.length;int k = 1;int i = 2;int j;
d2[0][0]=Tool.unsignDecoder(x[1]);d2[1][0]=0;d2[2][0]=1;
while(d2[0][k-1]!=218){
d2[1][k]=i;
d2[0][k]=Tool.unsignDecoder(x[i+1]);
i=i+2+Tool.unsignDecoder(x[i+2])*256+Tool.unsignDecoder(x[i+3]);
d2[2][k]=i-1;
k=k+1;
}
for (j=s-1;j<i;j--){
if((Tool.unsignDecoder(x[j-1])==255)&&(Tool.unsignDecoder(x[j])==217)) break;
}
d2[0][k]=217;d2[1][k]=i;d2[2][k]=j+1;
return d2;
}
public void cutdata(byte[] x,int[][] d){
int a =Tool.indexOf_1(d[0],218);
int b =Tool.indexOf_1(d[0],217);
head = Arrays.copyOfRange(x, 0, d[2][a]+1);
byte[] im = Arrays.copyOfRange(x, d[1][b], d[2][b]-1);//-2:delete the last EOI message.
im1 = new byte[im.length];
int j=0;int i=0;//dynamically record the length of the revised sequence
while(i<im.length){
im1[j]=im[i];
j++;
if((i!=im.length-1)&&(Tool.unsignDecoder(im[i])==255)&&(Tool.unsignDecoder(im[i+1]))==0){
i++;//move rightward i
}
i++;
}
im1=Arrays.copyOfRange(im1, 0, j);//delete zeros in the end of the sequence
}
public void sof(byte[] x,int[][] d){
int z = Tool.indexOf_1(d[0],192);
int i = d[1][z];
int[] temp = new int[19];
for(int j=0;j<19;j++){
temp[j]=Tool.unsignDecoder(x[j+i]);
}
int ph=i+5;int pw=i+7;
size[0] = Tool.unsignDecoder(x[ph])*256+Tool.unsignDecoder(x[ph+1]);
size[1] = Tool.unsignDecoder(x[pw])*256+Tool.unsignDecoder(x[pw+1]);
i += 11;//skip some unused letters
for(int j=0;j<3;j++){
int k = Tool.unsignDecoder(x[i]);
Q[j][0] = (k & 0xF0)/16;
Q[j][1] = k & 0x0F;
i += 3;
}
}
public void hfm(byte[] x,int[][] d){
//the DHT marker may appear several times in a JPEG, or several huffman trees can be found in a single DHT.
ArrayList res =Tool.indexOf(d[0],196);int thisLength;int pointer;int pointerOrigin;
int a;int huffLength = 0;
for(int z=0;z<res.size();z++){
a=(int) res.get(z);
pointer = d[1][a];pointerOrigin = d[1][a]+2;//please follow the straight-forward moving of this pointer
thisLength = Tool.unsignDecoder(x[pointer+2])*256+Tool.unsignDecoder(x[pointer+3]);
int[] temp = new int[thisLength+4];
for(int i=0;i<thisLength;i++){
temp[i]=Tool.unsignDecoder(x[pointer+i]);
}
pointer += 4;
while(huffLength<thisLength){
int mode = Tool.unsignDecoder(x[pointer]);pointer += 1;
int[] huff_num = new int[16];int total=0;
for(int i=0;i<16;i++){//码字总个数
huff_num[i] = x[pointer+i];total+=huff_num[i];
}
pointer +=16;int codePointer=0;int code=0;
int[][] huffmanTree = new int[3][total];
for(int i=0;i<16;i++){
if(i!=0){
code *= 2;
}
for(int j=0;j<huff_num[i];j++){
huffmanTree[0][codePointer]=i+1;
huffmanTree[1][codePointer]=code;
huffmanTree[2][codePointer]=Tool.unsignDecoder(x[pointer+codePointer]);
code++;codePointer++;
}
}
huffLength += pointer + codePointer - pointerOrigin;pointer += codePointer;
pointerOrigin = pointer;
switch(mode){
case(0):d0 = huffmanTree;break;
case(1):d1 = huffmanTree;break;
case(16):a0 = huffmanTree;break;
case(17):a1 = huffmanTree;break;
}
}
}
}
public void dri(byte[] x,int[][] d){
int z = Tool.indexOf_1(d[0],221);
if(z!=-1){
int pointer = d[1][z];
int len = Tool.unsignDecoder(x[pointer+2])*256+Tool.unsignDecoder(x[pointer+3]);
int[] temp = new int[len+2];
for(int i=0;i<len;i++){
temp[i]=Tool.unsignDecoder(x[pointer+i]);
}
DRI = Tool.unsignDecoder(x[d[1][z]+4])*256+Tool.unsignDecoder(x[d[1][z]+5]);}
}
public void sos(byte[] x,int[][] d){
int z = Tool.indexOf_1(d[0],218);int a = d[1][z];
int len = Tool.unsignDecoder(x[a+2])*256+Tool.unsignDecoder(x[a+3]);
int[] temp = new int[len+2];
for(int j=0;j<len+2;j++){
temp[j]=Tool.unsignDecoder(x[j+a]);
}
int pointer = d[1][z]+6;
for(int j=0;j<3;j++){
treeSelect[j] = Tool.unsignDecoder(x[pointer]);
pointer += 2;
}
}

Related

issues with Optimizing Speed and Strings

How can I optimize the processing of strings?
Your problem is you are making n copies of t and concatenating them. This is a simple approach, but quite expensive - it turns what could be an O(n) solution into an O(n2) one.
Instead, just check each char of s:
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != t.charAt(i % t.length())) {
return -1:
}
}
Do not make new strings, but use String.regionMatches.
Use String.length and modulo % == 0.
The smallest substring of t can be done using the same method.
Coding:
new String(string) ist never needed.
String += is slow. Better use StringBuilder.
No code to not spoil your coding.
Just a remark:
in general working with char[] is much faster than working with String.
(but nowhere near as convenient)
And make your variables final when they are final.
(it makes no difference to performance, but aids understanding)
Anyway, this might do it:
import java.util.Arrays;
class Result {
public static int findSmallestDivisor(final String s, final String t) {
final int lenS = s.length();
final int lenT = t.length();
/*
* Get Length & Chars of shortest & longest Strings...
*/
final int lenShort;
final int lenLong;
final char[] charsShort;
final char[] charsLong;
if (lenS < lenT) {
lenShort = lenS; charsShort = s.toCharArray();
lenLong = lenT; charsLong = t.toCharArray();
} else {
lenShort = lenT; charsShort = t.toCharArray();
lenLong = lenS; charsLong = s.toCharArray();
}
/*
* Get the Factor & exit if there's a remainder...
*/
final int factor = lenLong / lenShort;
final int factorRem = lenLong % lenShort;
if (factorRem != 0) {
return -1;
}
/*
* Try all possible divisors...
*/
for (int d=1; d <= lenShort; d++) {
final int n = lenShort / d;
final int nRem = lenShort % d;
if (nRem != 0) {
continue;
}
final char[] dChars = Arrays.copyOf(charsShort, d);
final char[] dCharsMultipliedShort = multiplyChars(dChars, n);
final char[] dCharsMultipliedLong = multiplyChars(dCharsMultipliedShort, factor);
if (Arrays.equals(charsShort, dCharsMultipliedShort)
&& Arrays.equals(charsLong, dCharsMultipliedLong )) {
return d;
}
}
return -1;
}
private static char[] multiplyChars(final char[] a, final int n) {
// if (n == 0) { // Necessary: otherwise ArrayIndexOutOfBoundsException in getChars(...)
// return new char[] {}; // (n is never 0)
// }
if (n == 1) { // Optional: optimisation
return a;
}
final int aLength = a.length;
final char[] charsMultiplied = new char[aLength * n];
System.arraycopy(a, 0, charsMultiplied, 0, aLength); // Fill in 1st occurrence
/*
* Copy 1st occurrence to the remaining occurrences...
*/
for (int i = 1; i < n; i++) {
System.arraycopy(charsMultiplied, 0, charsMultiplied, i*aLength, aLength);
}
return charsMultiplied;
}
}

Issue with Photometric Interpretation tag even after inverting the image data

Note: Giving the background of my previous question once again so as to find all the related stuff at one source.
I'm capturing an image from an android mobile device and it’s in JPEG format. The image is of 72X72DPI and 24 bit. When I try to convert this JPEG image to TIFF using LibTiff.Net and to set the tag Photometric Interpretation = 0 for MinIsWhite, the image turns negative (the white becomes black and black becomes white). The environment is Windows 8.1 64 bit, Visual Studio 2012. The tag must have value 0, where 0 = white is zero.
I absolutely must use Photometric.MINISWHITE in images so tried inverting image data before writing it to TIFF as per the below code. But then the compression changes to LZW instead of CCITT4,Photometric is changed to MINISBLACK from MINISWHITE, FIllorder tag is removed, PlanarConfig tag is removed, New tag Predictor is added with value 1 and the image turns negative again.
public partial class Form1 : Form
{
private const TiffTag TIFFTAG_ASCIITAG = (TiffTag)666;
private const TiffTag TIFFTAG_LONGTAG = (TiffTag)667;
private const TiffTag TIFFTAG_SHORTTAG = (TiffTag)668;
private const TiffTag TIFFTAG_RATIONALTAG = (TiffTag)669;
private const TiffTag TIFFTAG_FLOATTAG = (TiffTag)670;
private const TiffTag TIFFTAG_DOUBLETAG = (TiffTag)671;
private const TiffTag TIFFTAG_BYTETAG = (TiffTag)672;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (Bitmap bmp = new Bitmap(#"D:\Projects\ITests\images\IMG_2.jpg"))
{
// convert jpg image to tiff
byte[] tiffBytes = GetTiffImageBytes(bmp, false);
File.WriteAllBytes(#"D:\Projects\ITests\images\output.tif", tiffBytes);
//Invert the tiff image
Bitmap bmpTiff = new Bitmap(#"D:\Projects\ITests\images\output.tif");
Bitmap FBitmap = Transform(bmpTiff);
FBitmap.Save(#"D:\Projects\ITests\images\invOutput1.tif");
}
}
public static byte[] GetTiffImageBytes(Bitmap img, bool byScanlines)
{
try
{
byte[] raster = GetImageRasterBytes(img);
using (MemoryStream ms = new MemoryStream())
{
using (Tiff tif = Tiff.ClientOpen("InMemory", "w", ms, new TiffStream()))
{
if (tif == null)
return null;
tif.SetField(TiffTag.IMAGEWIDTH, img.Width);
tif.SetField(TiffTag.IMAGELENGTH, img.Height);
tif.SetField(TiffTag.COMPRESSION, Compression.CCITTFAX4);
tif.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISWHITE);
tif.SetField(TiffTag.ROWSPERSTRIP, img.Height);
tif.SetField(TiffTag.XRESOLUTION, 200);
tif.SetField(TiffTag.YRESOLUTION, 200);
tif.SetField(TiffTag.SUBFILETYPE, 0);
tif.SetField(TiffTag.BITSPERSAMPLE, 1);
tif.SetField(TiffTag.FILLORDER, FillOrder.LSB2MSB);
tif.SetField(TiffTag.ORIENTATION, BitMiracle.LibTiff.Classic.Orientation.TOPLEFT);
tif.SetField(TiffTag.SAMPLESPERPIXEL, 1);
tif.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.INCH);
tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
int tiffStride = tif.ScanlineSize();
int stride = raster.Length / img.Height;
if (byScanlines)
{
// raster stride MAY be bigger than TIFF stride (due to padding in raster bits)
for (int i = 0, offset = 0; i < img.Height; i++)
{
bool res = tif.WriteScanline(raster, offset, i, 0);
if (!res)
return null;
offset += stride;
}
}
else
{
if (tiffStride < stride)
{
// raster stride is bigger than TIFF stride
// this is due to padding in raster bits
// we need to create correct TIFF strip and write it into TIFF
byte[] stripBits = new byte[tiffStride * img.Height];
for (int i = 0, rasterPos = 0, stripPos = 0; i < img.Height; i++)
{
System.Buffer.BlockCopy(raster, rasterPos, stripBits, stripPos, tiffStride);
rasterPos += stride;
stripPos += tiffStride;
}
// Write the information to the file
int n = tif.WriteEncodedStrip(0, stripBits, stripBits.Length);
if (n <= 0)
return null;
}
else
{
// Write the information to the file
int n = tif.WriteEncodedStrip(0, raster, raster.Length);
if (n <= 0)
return null;
}
}
}
return ms.GetBuffer();
}
}
catch (Exception)
{
return null;
}
}
public static byte[] GetImageRasterBytes(Bitmap img)
{
// Specify full image
Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
Bitmap bmp = img;
byte[] bits = null;
try
{
// Lock the managed memory
if (img.PixelFormat != PixelFormat.Format1bppIndexed)
bmp = convertToBitonal(img);
BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format1bppIndexed);
// Declare an array to hold the bytes of the bitmap.
bits = new byte[bmpdata.Stride * bmpdata.Height];
// Copy the sample values into the array.
Marshal.Copy(bmpdata.Scan0, bits, 0, bits.Length);
// Release managed memory
bmp.UnlockBits(bmpdata);
}
finally
{
if (bmp != img)
bmp.Dispose();
}
return bits;
}
private static Bitmap convertToBitonal(Bitmap original)
{
int sourceStride;
byte[] sourceBuffer = extractBytes(original, out sourceStride);
// Create destination bitmap
Bitmap destination = new Bitmap(original.Width, original.Height,
PixelFormat.Format1bppIndexed);
destination.SetResolution(original.HorizontalResolution, original.VerticalResolution);
// Lock destination bitmap in memory
BitmapData destinationData = destination.LockBits(
new Rectangle(0, 0, destination.Width, destination.Height),
ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
// Create buffer for destination bitmap bits
int imageSize = destinationData.Stride * destinationData.Height;
byte[] destinationBuffer = new byte[imageSize];
int sourceIndex = 0;
int destinationIndex = 0;
int pixelTotal = 0;
byte destinationValue = 0;
int pixelValue = 128;
int height = destination.Height;
int width = destination.Width;
int threshold = 500;
for (int y = 0; y < height; y++)
{
sourceIndex = y * sourceStride;
destinationIndex = y * destinationData.Stride;
destinationValue = 0;
pixelValue = 128;
for (int x = 0; x < width; x++)
{
// Compute pixel brightness (i.e. total of Red, Green, and Blue values)
pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] +
sourceBuffer[sourceIndex + 3];
if (pixelTotal > threshold)
destinationValue += (byte)pixelValue;
if (pixelValue == 1)
{
destinationBuffer[destinationIndex] = destinationValue;
destinationIndex++;
destinationValue = 0;
pixelValue = 128;
}
else
{
pixelValue >>= 1;
}
sourceIndex += 4;
}
if (pixelValue != 128)
destinationBuffer[destinationIndex] = destinationValue;
}
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);
destination.UnlockBits(destinationData);
return destination;
}
private static byte[] extractBytes(Bitmap original, out int stride)
{
Bitmap source = null;
try
{
// If original bitmap is not already in 32 BPP, ARGB format, then convert
if (original.PixelFormat != PixelFormat.Format32bppArgb)
{
source = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb);
source.SetResolution(original.HorizontalResolution, original.VerticalResolution);
using (Graphics g = Graphics.FromImage(source))
{
g.DrawImageUnscaled(original, 0, 0);
}
}
else
{
source = original;
}
// Lock source bitmap in memory
BitmapData sourceData = source.LockBits(
new Rectangle(0, 0, source.Width, source.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// Copy image data to binary array
int imageSize = sourceData.Stride * sourceData.Height;
byte[] sourceBuffer = new byte[imageSize];
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);
// Unlock source bitmap
source.UnlockBits(sourceData);
stride = sourceData.Stride;
return sourceBuffer;
}
finally
{
if (source != original)
source.Dispose();
}
}
public Bitmap Transform(Bitmap bitmapImage)
{
var bitmapRead = bitmapImage.LockBits(new Rectangle(0, 0, bitmapImage.Width, bitmapImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
var bitmapLength = bitmapRead.Stride * bitmapRead.Height;
var bitmapBGRA = new byte[bitmapLength];
Marshal.Copy(bitmapRead.Scan0, bitmapBGRA, 0, bitmapLength);
bitmapImage.UnlockBits(bitmapRead);
for (int i = 0; i < bitmapLength; i += 4)
{
bitmapBGRA[i] = (byte)(255 - bitmapBGRA[i]);
bitmapBGRA[i + 1] = (byte)(255 - bitmapBGRA[i + 1]);
bitmapBGRA[i + 2] = (byte)(255 - bitmapBGRA[i + 2]);
// [i + 3] = ALPHA.
}
var bitmapWrite = bitmapImage.LockBits(new Rectangle(0, 0, bitmapImage.Width, bitmapImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb);
Marshal.Copy(bitmapBGRA, 0, bitmapWrite.Scan0, bitmapLength);
bitmapImage.UnlockBits(bitmapWrite);
return bitmapImage;
}
}
You should invert image bytes in GetTiffImageBytes method, before writing them to TIFF. Also, the Transform method converts bi-level image to 32bpp one and that is why you get LZW compressed image in the end.
So, add the following code
for (int k = 0; k < raster.Length; k++)
raster[k] = (byte)(~raster[k]);
after byte[] raster = GetImageRasterBytes(img); in GetTiffImageBytes method. This will invert image bytes. And don't use the following code
//Invert the tiff image
Bitmap bmpTiff = new Bitmap(#"D:\Projects\ITests\images\output.tif");
Bitmap FBitmap = Transform(bmpTiff);
FBitmap.Save(#"D:\Projects\ITests\images\invOutput1.tif");

Counting Shapes/Objects Created Continuously within Processing

My code takes an image and creates a pointillist image through creating ellipses with a pixel's color.
After a while, the image is fully 'painted' and I want to automatically switch to another image in my sketch folder.
I would like to be able to count the number of ellipses generated. Once 'z' ellipses are generated I want to tell my code to erase all ellipses and start over with a new image.
CODE:
PImage img;
int smallPoint, largePoint;
void setup() {
size(1920, 1080);
img = loadImage("rio.jpg");
smallPoint = 12;
largePoint = 12;
imageMode(CENTER);
noStroke();
background(255);
}
void draw() {
for (int i = 0; i < 1000; i++)
{
drawADot();
}
}
void drawADot()
{
int imageWidth = img.width;
int imageHeight = img.height;
int ptSize = int(random(100)) + 4;
float pointillize = map(mouseX, 0, width, smallPoint, largePoint); //not used right now but for controlling ellipse size
int x = int(random(0, imageWidth/8));
int y = int(random(0, imageHeight/8));
color pix = img.get(x*8, y*8);
fill(pix, 255);
ellipse(x*8, y*8, pointillize, pointillize);
}
Store the images in an array, count the dots added, and conditionally (based in number of dots) change the image being used to next one in the array, you can pass the image to the drawADot() function as a parameter. Something like:
PImage img[] = new PImage[2];
int smallPoint, largePoint;
final int DOTSPERDRAW = 500;
int numberOfDots = 0;
final int MAXDOTS = DOTSPERDRAW * 100;
PImage workingImage ;
int index;
void setup() {
size(810, 455);
img[0] = loadImage("http://assets2.exame.abril.com.br/assets/images/2014/8/506584/size_810_16_9_rio.jpg");
img[1] = loadImage("http://upload.wikimedia.org/wikipedia/commons/1/1e/Pilcomayo_rio.jpg");
img[1].resize(810, 0);
smallPoint = 12;
largePoint = 12;
imageMode(CENTER);
noStroke();
background(255);
workingImage = img[0];
}
void draw() {
if (numberOfDots > MAXDOTS) {
index = (index + 1) % img.length;
workingImage = img[index];
numberOfDots = 0;
}
for (int i = 0; i < DOTSPERDRAW; i++)
{
drawADot(workingImage);
}
numberOfDots += DOTSPERDRAW;
}
void drawADot(PImage theImage)
{
int imageWidth = theImage.width;
int imageHeight = theImage.height;
int ptSize = int(random(100)) + 4;
float pointillize = map(mouseX, 0, width, smallPoint, largePoint); //not used right now but for controlling ellipse size
int x = int(random(0, imageWidth/8));
int y = int(random(0, imageHeight/8));
color pix = theImage.get(x*8, y*8);
fill(pix, 255);
ellipse(x*8, y*8, pointillize, pointillize);
}

Passing an array of object from one class to another

I've been trying to create a program where it takes an array input through an object and passes the parameter (simulation of ArrayList).
I keep getting the java.lang.ArrayIndexOutOfBoundsException in which I'm guessing I'm not accessing the array properly..
What can I do to enhance the test object and/ or the constructor?
public class MyArrayList{
public int[] x;
public MyArrayList( ){
x = new int[0];
}
public MyArrayList(int[] k)
{
for (int i = 0; i < x.length; i++)
x[i] = k[i];
k = x;
}
public void add(int index).......
public int size().....
public int get(int index).....
public void set(int index, int value).......
public String toString( )........
Below is the class I am having trouble with.
public class TestMyArrayList
{
public static void main(String[] args)
{
MyArrayList test = new MyArrayList();
test.x[0] = 1;
test.x[1] = 2;
test.x[2] = 3;
test.x[3] = 4;
test.x[4] = 5;
test.add(2);
test.set(1,3);
int a, b;
String c;
a = test.size( );
b = test.get(5);
c = test.toString( );
System.out.println("The size of the array is" + a);
System.out.println("The value at that position is " + b);
System.out.println("The resulting string is: " + c);
}
}
This line from your constructor is the only location (in the code you've shown) where the array x is initialized:
x = new int[0];
And it creates a zero length array. Assuming you are not reinitializing the array somewhere else then all these lines will definitely fail:
test.x[0] = 1;
test.x[1] = 2;
test.x[2] = 3;
test.x[3] = 4;
test.x[4] = 5;
Because your array length is zero. So:
Initialize your array to a more sensible value
Consider encapsulating the array so that callers cannot directly access it. This will make it much easier to code up your application in the long run
Side note (aka bonus):
This other constructor of yours:
public MyArrayList(int[] k) {
for (int i = 0; i < x.length; i++)
x[i] = k[i];
k = x;
}
has some issues as well:
You should reinitialize your array x to be the same size as the supplied array, prior to copying over the values.
The assignment k = x is basically a no-op, because it doesn't actually change what k was pointing to outside of the method.
Overall, it should look more like this:
public MyArrayList(int[] k) {
super();
if(k != null) {
x = new int[k.length];
for (int i = 0; i < x.length; i++) {
x[i] = k[i];
}
} else {
x = null;
}
}

ReadLine - Array index out of bounds

I have been debugging this program to find the error but couldn't succeed in that. For some reason, it is displaying an error - array index out of bounds in this line
moves[nCount].sDirection = sStep[0]; I know, this forum is not meant for debugging, im sorry for that.
class Program
{
struct move
{
public char sDirection;
public int steps;
}
static void Main(string[] args)
{
int nNumOfInstructions = 0;
int nStartX = 0, nStartY = 0;
move[] moves = new move[nNumOfInstructions];
nNumOfInstructions=Convert.ToInt32(Console.ReadLine());
string sPosCoOrd = Console.ReadLine();
nStartX = Convert.ToInt32(sPosCoOrd[0]);
nStartY = Convert.ToInt32(sPosCoOrd[2]);
string sStep = "";
for (int nCount = 0; nCount < nNumOfInstructions; nCount++)
{
sStep = Console.ReadLine();
int length = sStep.Length;
moves[nCount].sDirection = sStep[0];
moves[nCount].steps = Convert.ToInt32(sStep[1]);
}
Console.ReadLine();
}
}
In your code, the moves array is created as an array of zero length. For any index, accessing this array will inevitably throw an Array index out of bounds
You probably want to do it this way:
class Program
{
struct move
{
public char sDirection;
public int steps;
}
static void Main(string[] args)
{
int nNumOfInstructions = Convert.ToInt32(Console.ReadLine());
move[] moves = new move[nNumOfInstructions];
string sPosCoOrd = Console.ReadLine();
int nStartX = Convert.ToInt32(sPosCoOrd[0]);
int nStartY = Convert.ToInt32(sPosCoOrd[2]);
string sStep = String.Empty;
for (int nCount = 0; nCount < nNumOfInstructions; nCount++)
{
sStep = Console.ReadLine();
int length = sStep.Length;
moves[nCount].sDirection = sStep[0];
moves[nCount].steps = Convert.ToInt32(sStep[1]);
}
}
}

Resources